이번에는 vue addRoutes를 사용하여 동적 권한 라우팅 메뉴를 구현하는 방법과 vue addRoutes를 사용하여 동적 권한 라우팅 메뉴를 구현하는 방법에 대한 주의 사항에 대해 설명하겠습니다.
Requirements
최근 백엔드 관리 시스템을 인수하여 백엔드에서 탐색 메뉴를 가져오는 효과를 구현해야 했습니다. 가져온 탐색 메뉴는 로그인한 사용자의 권한에 따라 다릅니다. 작동 가능한 인터페이스도 있습니다.
문제
백그라운드 관리 시스템은 vue+vue-router+element-ui+vuex의 조합을 사용하도록 준비되어 있지만 단일 페이지 애플리케이션이 페이지에 들어가기 전에 vue-router를 인스턴스화했기 때문에 vue 인스턴스에 주입되므로 로그인 페이지에 들어갈 때 경로를 다시 사용자 정의할 수 있는 방법이 없습니다. 많은 검색 끝에 vue-router가 버전 2.0에서 경로를 추가하는 addRoutes 메소드를 제공한다는 것을 알았고, 희미한 희망이 나타났습니다.
많은 노력 끝에 마침내 기능을 구현하게 되었습니다. 쉽게 복습할 수 있도록 녹음해 두었습니다. 또한 같은 요구 사항을 갖고 있는 동지들에게 도움이 되기를 바랍니다.
아이디어
1. 먼저 다음과 같이 로그인, 404 페이지와 같은 고정 라우팅 주소를 로컬로 구성합니다.
import Vue from 'vue' import Router from 'vue-router' import store from '@/vuex/store' Vue.use(Router) let router = new Router({ routes: [ { path: '/login', name: 'login', meta: {requireAuth: false}, // 模块使用异步加载 component: (resolve) => require(['../components/login/login.vue'], resolve) }] }) // 拦截登录,token验证 router.beforeEach((to, from, next) => { if (to.meta.requireAuth === undefined) { if (store.state.token) { next() } else { next({ path: '/login' }) } } else { next() } }) export default router
이러한 고정 경로를 구성한 후 로그인 페이지로 이동할 수 있습니다. 계속하세요.
2. 그런 다음 중요한 단계는 먼저 반환해야 하는 권한 메뉴 목록 정보에 대해 백엔드 베테랑과 동의해야 한다는 것입니다. 여기서는 필요한 라우팅 구조를 분석해 보겠습니다. 예. 내가 직접 경로를 정의하면 다음과 같은 구조를 가지게 됩니다.
let router = new Router({ routes: [ { path: '/login', name: 'login', meta: {requireAuth: false}, component: (resolve) => require(['../components/login/login.vue'], resolve) }, { path: '/', redirect: '/layout' }, { path: '/layout', component: (resolve) => require(['../layout.vue'], resolve), children: [ { path: 'index', meta: { type: '1', //控制是否显示隐藏 1显示,2隐藏 code: 00010001, // 后面需要控制路由高亮 title: '首页', // 菜单名称 permissonList: [] // 权限列表 } component: (resolve) => require(['@/components/index/index.vue'], resolve) }, { ... } ] }] })
위의 구조 분석에 따르면 실제로 동적으로 구성해야 하는 경로는 실제로는 /layout 아래의 하위 부분이므로 백엔드는 필요합니다. 모든 경로가 포함된 경로를 반환하려면 배열이면 충분합니다
반환된 데이터에서 rootList는 첫 번째 수준 탐색 목록이며 실제로는 라우팅 기능만 사용됩니다. 하위 목록은 우리에게 정말로 필요한 라우팅 정보입니다.
3. 권한 라우팅 정보를 얻은 후 데이터를 로컬에서 처리하여 필요한 데이터로 조합해야 합니다.
// 登录 login () { let params = { account: this.loginForm.username, password: encrypt(this.loginForm.password) } this.loading = true this.$http.post(this.$bumng + '/login', this.$HP(params)) .then((res) => { this.loging = false console.info('菜单列表:', res) if (res.resultCode === this.$state_ok) { // 合并一级菜单和二级菜单,便于显示 let menus = handleMenu.mergeSubInRoot(res.rootList, res.subList) // 本地化处理好的菜单列表 this.saveRes({label: 'menuList', value: menus}) // 根据subList处理路由 let routes = handleMenu.mergeRoutes(res.subList) // 本地化subList,便于在刷新页面的时候重新配置路由 this.saveRes({label: 'subList', value: res.subList}) // 防止重复配置相同路由 if (this.$router.options.routes.length <= 1) { this.$router.addRoutes(routes) // this.$router不是响应式的,所以手动将路由元注入路由对象 this.$router.options.routes.push(routes) } this.$router.replace('/layout/index') } }) .catch((err) => { this.loging = false console.error('错误:', err) }) },
메뉴 목록 및 하위 목록 처리 방법: mergeSubInRoot 및 mergeRoutes
const routes = [ { path: '/', redirect: '/layout' }, { path: '/layout', component: (resolve) => require(['../layout.vue'], resolve), children: [] } ] export default { /** * 合并主菜单和子菜单 * @param: rootList [Array] 主菜单列表 * @param: subList [Array] 子菜单 * */ mergeSubInRoot (roots, subs) { if (roots && subs) { for (let i = 0; i < roots.length; i++) { let rootCode = roots[i].code roots[i].children = [] for (let j = 0; j < subs.length; j++) { if (rootCode === subs[j].code.substring(0, 4)) { roots[i].children.push(subs[j]) } } } } return roots }, /** * 合并远程路由到本地路由 * @param: subList [Array] 远程路由列表 * @param: routes [Array] 本地路由列表 * */ mergeRoutes (subs) { if (subs) { for (let i = 0; i < subs.length; i++) { let temp = { path: subs[i].actUrl, name: subs[i].actUrl, component: (resolve) => require([`@/components/${subs[i].component}.vue`], resolve), meta: { type: subs[i].type, code: subs[i].code, title: subs[i].name, permissionList: subs[i].permissionList } } routes[1].children.push(temp) } } return routes } }
지금까지 성공적으로 라우팅했습니다. 권한 로컬 라우팅에 구성된 내 시스템 로그인은 다음과 같습니다
후속 최적화1. 메뉴 목록 표시 및 보조 탐색 전환:
<template> <p class="mainMenu"> <el-menu class="menubar" mode="horizontal" :default-active="activeCode" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"> <el-menu-item :index="item.code | splitCode" v-for="item in menuList" :key="item.code" @click="switchSubMenu(item)" v-if="item.code !== '0008'"> <i :class="`iconfont icon-${item.imgUrl}`"></i> <span slot="title">{{item.name}}</span> </el-menu-item> </el-menu> </p> </template> <script type="text/ecmascript-6"> import {mapState, mapMutations} from 'vuex' export default { name: 'menu', data () { return { msg: 'Welcome to Your Vue.js App' } }, computed: { ...mapState(['menuList']), activeCode () { // 通过code保证在切换字路由的情况下一级路由也是高亮显示 return this.$route.meta.code.substring(0, 4) } }, methods: { ...mapMutations(['saveRes']), // 切换二级路由 switchSubMenu (route) { console.info('路由:', route) if (route.actUrl !== 'index') { // 用currentSubMenu控制二级路由数据 this.saveRes({label: 'currentSubMenu', value: route.children}) this.$router.push(`/layout/${route.children[0].actUrl}`) } else { // 不存在二级路由隐藏二级 this.saveRes({label: 'currentSubMenu', value: ''}) this.$router.push(`/layout/${route.actUrl}`) } } }, filters: { splitCode (code) { return code.substring(0, 4) } } } </script>
2. 새로 고침으로 인해 이때 단일 페이지 애플리케이션이 다시 초기화됩니다. 이때 구성된 경로는 모두 손실됩니다. 일단 해방되기 전에는 로컬로 구성된 경로만 점프할 수 있습니다. 이때 app.vue에서 다음 코드를 실행할 수 있습니다. (ps: 새로 고침이 수행된 위치에 관계없이 app.vue가 실행됩니다.)
<script> import {decrypt} from '@/libs/AES' import handleMenu from '@/router/handleMenu' export default { name: 'app', created () { // 当this.$router.options.routes的长度为1,且本地缓存存在菜单列表的时候才重新配置路由 if (this.$router.options.routes.length <= 1 && sessionStorage.getItem('subList')) { let subList = JSON.parse(decrypt(sessionStorage.getItem('subList'))) let routes = handleMenu.mergeRoutes(subList) this.$router.addRoutes(routes) // this.$router不是响应式的,所以手动将路由元注入路由对象 this.$router.options.routes.push(routes) } } } </script>
이렇게 하면 새로 고쳐도 라우팅이 재구성됩니다.
3. 페이지 버튼 수준 제어와 관련하여 이를 수행하는 명령을 사용자 정의할 수 있습니다. 해당 경로의 메타 객체에 권한 목록을 넣어두었기 때문에 현재 사용자가 각 페이지에서 가지고 있는 권한으로 쉽게 돌아갈 수 있습니다
이 글을 읽으신 후 마스터하셨으리라 믿습니다. 이 기사의 방법에 대한 사례입니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!
추천 자료:
create-react-app을 사용하여 React 개발 환경을 구축하는 방법에 대한 자세한 단계별 설명element-ui를 사용하여 날짜 선택을 제한하는 방법위 내용은 vue addRoutes를 사용하여 동적 권한 라우팅 메뉴를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!