vue3+element-plus 实现动态菜单和动态路由的渲染,中后台管理系统实战(前后端分离版)

目录

     前言

      前期准备

      动态菜单

      动态路由

前言

本文章旨在从零搭建一个动态菜单,动态路由的中后台管理系统的初始环境,可能有些地方不会那么完美,请多多指教

前期准备

本文需要使用路由,安装element-plus ,数据我都是mock的,并且是基于vue3的js而并非ts,环境的搭建我们在这里不做过多的描述,需要自己手动完成

1、首先我们先安装一下element-plus

     1) 根据官网上的描述

      

如果您的网络环境不太好的话,建议您使用cnpm来进行安装

完整引入:

如果您对您的打包体积无所谓的话,可以使用完整引入的方法     

按需导入:

  建议您使用按需引入的方法来完成,打包体积小,速度快

  需要您安装两个插件

npm install -D unplugin-vue-components unplugin-auto-import

注:如果启动的时候爆出错误:

  1. ERROR  TypeError: AutoImport is not a function

    原因是:unplugin-auto-import插件版本问题 查看unplugin-auto-import插件版本

  2. ERROR  TypeError: components is not a function                                                                    原因是:unplugin-auto-import插件版本问题 查看unplugin-components-import插件版本

版本回退:

npm install unplugin-auto-import@0.16.1

npm install unplugin-components-import@0.20.1 

 然后再vue.config.js中进行配置

const { defineConfig } = require("@vue/cli-service");
// webpack.config.js
const AutoImport = require("unplugin-auto-import/webpack");
const Components = require("unplugin-vue-components/webpack");
const { ElementPlusResolver } = require("unplugin-vue-components/resolvers");
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false, //关闭语法检查器
  configureWebpack: {
    plugins: [
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
    ],
  },
});

重新启动即可

动态菜单

  在这之前我们需要一个布局,我这里使用的是element-plus的container布局容器进行的布局

假设我们的App.vue组件如下

下面正片开始

功能:

     1、根据不同的角色来显示不同的菜单,菜单的数据一般都是由后端来提供,前端负责渲染即可,但是我这里的菜单是自己mock的,只用来演示

    2、获取菜单->缓存到localstorage里面->渲染菜单

我们使用element-plus的menu菜单来进行渲染:

  

获取菜单

首先我们需要先获取到菜单,一般都是在登录的时候获取,然后根据自己的情况来自定义,但是我是自己mock的所以跳过请求的的一部分  我只在初始化的时候获取到菜单

如有需要,请联系我哦

生成菜单

 获取到了菜单之后,我们就需要在首页中渲染菜单啦

使用明确:element-plus中menu主要分为两个状态:有子菜单(目录)和没有子菜单,我们需要根据这两种情况分别去渲染

新建一个vue文件,我们假设这个组件是SideMenu

<template>
    <div>
        <!-- 标题logo -->
        <span class="demo">
            <!-- <img src="../../assets/image/jdtitle.png" alt="" /> -->
            标题logo
        </span>
        <el-menu
         active-text-color="#ffd04b"
          background-color="#242424"
           class="el-menu-vertical-demo"
            default-active="0"
            text-color="#fff"
             router="true">
            <MenuTree :menuList="subchildren"></MenuTree>
        </el-menu>

    </div>
</template>


<script setup>
import { ref, onMounted } from 'vue'
import children from "@/utils/index";
import MenuTree from './MenuTree'

const subchildren = ref([])
onMounted(() => {
    subchildren.value = children()
})

</script>

我们写到这里,可能会有小伙伴会疑惑了,诶怎么代码这么少?而且只有<el-menu>标签?渲染菜单的<el-sub-menu>和<el-menu-item>标签呢?

由于我们会采用地柜,如果把所有的代码都写在一个组件里面,那么所有元素都会重复了,比如说这个logo标题也会重复了,那肯定是不行的,所以我们需要将渲染菜单的具体操作写在另一个vue文件里面,具体的代码就在MenuTree组件里面

下面我们看看这个MenuTree里面

<script setup >
import { defineProps } from 'vue'
const props = defineProps(['menuList'])
</script>


<template>
    <div>
        <template v-for="item in props.menuList" :key="item.path">
            <!-- {{ item }} -->
            <!--      分为两种方式渲染:有子菜单和没有子菜单-->
            <el-sub-menu :index="item.path" v-if="item.children">
                <template #title>
                    <span>{{ item.title }}</span>
                </template>
                <!--        有子菜单的继续遍历(递归)-->
                <MenuTree :menuList="item.children"></MenuTree>
            </el-sub-menu>
            <!--      没有子菜单-->
            <el-menu-item :index="item.path" v-if="!item.children">
                <span>{{ item.title }}</span>
            </el-menu-item>
        </template>
    </div>
</template>


<style></style>

下面是渲染出来的结果

在上面的代码中

1、我使用children来判断是否存在子菜单

2、然后采用父子组件的传递数据的方法把菜单数据唇乳带渲染菜单的子组件中

写到这里我们的动态菜单的效果就已经结束了,但是这还不行,我们需要通过动态路由来进行页面的访问

动态路由:

首先我们先安装vue-router,如果你的vue的版本是3的话,那么我们安装的vue-router的版本要在4

npm install vue-router@4
创建路由:

我们需要在src里面创建一个router文件,首先定义一些静态路由何必要的路由配置创建

import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/home/Home.vue";
import Processcenter from "../views/processcenter/Processcenter";
const constRoutes = [
  {
    path: "/",
    redirect: "/content/home",
  },
  {
    path: "/content/home",
    component: Home,
  },
  {
    path: "/basicdata/processcenter",
    component: Processcenter,
  },
];

const routerHistory = createWebHistory();
const router = createRouter({
  history: routerHistory,
  routes: constRoutes,
});

export default router;

然后再main.js里面引入并使用

import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import router from "./router/router";
import App from "./App.vue";

const app = createApp(App);

app.use(ElementPlus);
app.use(router);  //使用路由
app.mount("#app");

最后在content组件里面使用 router-view来进行渲染


<template>
    <div>
        <router-view></router-view>
    </div>
</template>

截止到这,我们后台管理系统的基本环境已经搭建好了,我们来看一下效果:

欢迎小伙伴来进行批评和指正,如果喜欢的话给博主一个小红心吧😘

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
为了实现动态路由和用户权限路由,我们需要进行以下步骤: 1. 安装依赖 ```shell npm install vue-router@4 pinia element-plus mock -S npm install @types/mock -D ``` 2. 创建路由配置文件 在src文件夹下创建router文件夹,并在其创建index.ts文件,用于配置路由。在该文件,我们需要定义路由的各个页面组件,并根据需要配置路由的子路由和路由守卫。例如: ```typescript import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import Home from '@/views/home/indexName.vue' import Login from '@/views/login/index.vue' import NotFound from '@/views/404/index.vue' const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home, meta: { title: '首页', requireAuth: true // 需要登录才能访问 } }, { path: '/login', name: 'Login', component: Login, meta: { title: '登录' } }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound, meta: { title: '404' } } ] const router = createRouter({ history: createWebHistory(), routes }) // 路由守卫 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.meta.requireAuth && !token) { next('/login') } else { next() } }) export default router ``` 3. 在main.ts挂载路由 在main.ts,我们需要将路由配置文件挂载到Vue实例,以便在应用使用路由。例如: ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app') ``` 4. 创建权限控制文件 在src文件夹下创建permission文件夹,并在其创建index.ts文件,用于控制用户权限。在该文件,我们需要定义用户的权限列表,并根据需要判断用户是否有权限访问某个路由。例如: ```typescript import router from '@/router' const whiteList = ['/login'] // 不需要登录即可访问的页面 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (token) { if (to.path === '/login') { next('/') } else { // 判断用户是否有权限访问该路由 const hasPermission = true // 根据实际情况判断用户是否有权限 if (hasPermission) { next() } else { next('/404') } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next('/login') } } }) ``` 5. 在App.vue挂载路由渲染入口 在App.vue,我们需要将路由渲染入口挂载到模板,以便在应用渲染路由。例如: ```html <template> <div id="app"> <router-view /> </div> </template> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值