(二) Vue3 + Element-Plus 实现动态菜单栏

这篇具有很好参考价值的文章主要介绍了(二) Vue3 + Element-Plus 实现动态菜单栏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

  1. 系列介绍:Vue3 + Vite + TS 从零开始学习
  2. 项目搭建:(一) Vue3 + Vite + TS 项目搭建
  3. 实现动态菜单栏:(二) Vue3 + Element-Plus 实现动态菜单栏
  4. 实现动态面包屑:(三) Vue3 + Element-Plus 实现动态面包屑
  5. 实现动态标签页:(四) Vue3 + Element-Plus 实现动态标签页
  6. 实现动态主题色切换(demo):(五) Vue3 + Element-Plus 实现动态主题色切换
  7. 踩坑记录(持续更新):(六) Vue3 踩坑记录


一、引入依赖

开始前请确保已经安装以下依赖:

  1. VueX
$ npm i vuex --save
  1. Vue-Router
$ npm i vue-router --save
  1. NProgress
$ npm i nprogress --save

二、目录结构

|-src                   -- 主目录
---|api                 -- Ajax请求统一存放目录
------|auth-api.js      -- 路由数据获取接口
---|js                  -- JS脚本
------|permission.js    -- NProgress进度条数据处理
---|layout              -- 页面布局组件
------|sidebar.vue      -- 侧边栏布局组件
---|store               -- VueX
------|router.js        -- 路由全局常量

三、核心代码

1. auth-api.js

import request from '@/js/request'

export default {
  routers(data) {
    return request.post('/routers', data)
  }
}

2. permission.js

import router from '../router'
import store from '../store'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getCookie } from './cookie'
import Layout from '../layout/index.vue'
import ParentView from '../components/ParentView/index.vue'

NProgress.configure({ showSpinner: false })

const whiteList = ['/login', '/register']

router.beforeEach((to, from, next) => {
  NProgress.start()
  if (getCookie()) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      if (store.state.user.menus.length === 0) {
        store.dispatch('GetInfo').then(res => {
          const menuIds = res.data.menuIds
          store.dispatch('GenerateRoutes', menuIds).then(routes => {
            filterRoutes(routes)
            routes.forEach(route => {
              router.addRoute(route)
            })
            next({ ...to, replace: true })
          })
        }).catch(() => {
          next()
        })
      } else {
        next()
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})


const filterRoutes = (routes) => {
  const accessRoutes = routes.filter(route => {
    let modules = import.meta.glob('../views/**/*.vue')
    if (route.component) {
      if (route.component === 'ParentView') {
        route.component = ParentView
      } else if (route.component === 'Layout') {
        route.component = Layout
      } else {
        route.component = modules[`../views/${route.component}.vue`]
      }
    }
    if (route.children && route.children.length) {
      filterRoutes(route.children)
    }
    return true
  })
  return accessRoutes
}

3.sidebar.vue

<template>
  <el-aside width="210px" class="aside-wrapper">
    <el-scrollbar>
      <el-menu :default-active="route.path" mode="vertical" :collapse-transition="false" router class="menu-wrapper">
        <el-sub-menu v-for="menu in menus" :key="menu.path" :index="menu.path">
          <template #title>
            <el-icon><component :is="menu.meta.icon" /></el-icon>
            <span>{{ menu.name }}</span>
          </template>
          <el-menu-item v-for="child in menu.children" :key="child.path" :index="child.path">
            <template #title>
              <el-icon><component :is="child.meta.icon" /></el-icon>
              <span>{{ child.name }}</span>
            </template>
          </el-menu-item>
        </el-sub-menu>
      </el-menu>
    </el-scrollbar>
  </el-aside>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'

const store = useStore()
const route = useRoute()
const menus = store.state.router.accessRoutes

</script>

4.router.js

import { authApi } from '@/api'
import constantRoutes from '@/router/routes'

const router = {
  state: {
    routes: [],
    accessRoutes: []
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.routes = routes
    },
    SET_ACCESSROUTES: (state, accessRoutes) => {
      state.accessRoutes = accessRoutes
    }
  },
  actions: {
    GenerateRoutes({ commit }, roleIds) {
      return new Promise(resolve => {
        authApi.routers(roleIds).then(res => {
          const accessRoutes = res.data
          filterRoutes('', accessRoutes)
          const routes = constantRoutes.concat(accessRoutes)
          commit('SET_ROUTES', routes)
          commit('SET_ACCESSROUTES', accessRoutes)
          resolve(routes)
        })
      })
    }
  }
}

const filterRoutes = (path, routes) => {
  routes.forEach(route => {
    const routePath = route.path
    if (route.parentId !== '0') {
      route.path = path + "/" + routePath
    }
    if (route.children && route.children.length) {
      filterRoutes(routePath, route.children)
    }
  })
}

export default router

四、最终效果

(二) Vue3 + Element-Plus 实现动态菜单栏文章来源地址https://www.toymoban.com/news/detail-422368.html

到了这里,关于(二) Vue3 + Element-Plus 实现动态菜单栏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3+Element-Plus 实现用户列表页面的UI结构及动态加载表单功能 三一

    1.1 头部是一个面包屑 (Breadcrumb)导航区域 1.2 白色区域是一个卡片(Card)视图 1.3 卡片 (Card)视图中嵌套了   输入框(Input )、 按钮(Button)、 表单(Form)、分页(Pagination ) Breadcrumb 面包屑 | Element Plus (gitee.io) https://element-plus.gitee.io/zh-CN/component/breadcrumb.html  2.1.1 复制

    2023年04月09日
    浏览(58)
  • Vue3+Vue-Router+Element-Plus根据后端数据实现前端动态路由——权限管理模块

    提示:文章内容仔细看一些,或者直接粘贴复制,效果满满 提示:文章大概 1、项目:前后端分离 2、前端:基于Vite创建的Vue3项目 3、后端:没有,模拟的后端数据 4、关于路径“@”符号——vite.config.js 文件里修改 提示:以下是本篇文章正文内容,下面案例可供复制粘贴使用

    2024年02月02日
    浏览(64)
  • Vue3中动态绑定:disabled element-plus使用方法

    @change=\\\"whetherFlag($event)\\\"  根据value值判断是否禁用 :disabled=\\\"isShow\\\" 初始值为禁用状态 const isShow = refboolean(true);  根据value的值判断是否禁用  

    2024年01月25日
    浏览(60)
  • vue3 element-plus 实现图片预览

    element-plus下有这么一个组件 el-image-viewer /,但是这个组件是没写在文档上面的,像普通组件一样使用即可 可以通过点击按钮实现图片预览,而非el-image组件只能通过点击图片实现预览 2.1封装组件 2.3组件使用 在需要使用的地方引入,然后使用即可,这不是重点,每个人使用的

    2024年02月15日
    浏览(59)
  • Vue3+element-plus实现后台管理系统

     环境:node.js软件 、Vs code、vite、elemnt-plus、windicss(样式框架)     1、首先,使用npm 命令构建项目( vscode安装的插件 vscode中文显示插件   2、高亮提示插件volar   3、vue 3 sni 代码提示) 快速上手 | Vue.js    a. npm -v 查看node.js 版本    b.  npm  config get registry   查看注册镜像是

    2024年02月09日
    浏览(55)
  • Vue3使用element-plus实现弹窗效果-demo

    2024年02月13日
    浏览(52)
  • vue3+element-plus+el-image实现点击按钮预览大图

    需求:点击某个按钮实现el-image中预览大图的效果 官方文档:以下是官方的写法,并不能达到我们的要求,官方实现的功能是点击图片达到预览大图的效果。如果你的按钮就是图片,也可以达到目前的功能 el-image-viewer组件是element官方的组件,只是文档中没有写出来,这个组

    2024年02月12日
    浏览(58)
  • vue3+element-plus 通过v-infinite实现下拉滚动无限加载

    v-infinite官网 v-infinite-scroll无限滚动组件使用详解  官网给到的基础案例: 自己写了一个简单的demo: 当使用v-infinite时,控制台会报错:  原因: 官方上的Issues解释是需要nextTick()之后再去显示 解决方法是组件挂载完成再去显示el-select组件 所以在上面demo中select组件加了v-if,

    2024年02月09日
    浏览(52)
  • vue3.0+element Plus实现页面布局,侧边栏菜单路由跳转

    一. 先在router.js文件中配置路由,将侧边栏中需要跳转的页面都添加到children中 二. 在view目录下新建一个文件,里面包含侧边栏要跳转的页面 三.  页面样式布局 1. 我选择使用自定义组件BaseLayout.vue文件来设置header和aside样式显示 也可以使用element plus中的Container 布局容器 

    2024年02月13日
    浏览(51)
  • vue3+element-plus实现表格多选功能(可以清除选项或分页保留选项)

    如图所示,在实际开发中,数据量大的表格基本都添加上了分页功能,每个页面请求的数据回交换更新,第一页的选中效果在跳转至第二页后,如果没有做相关处理,选中项会被清空,具体解决方法如下 在需要处理的表格标签中加上 :row-key=\\\"getRowKeys\\\" 以及 @selection-change=“ha

    2024年02月12日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包