この記事では、addRoutes による動的許可ルーティング メニューの実装を主に紹介します。これには、必要な友人全員が参照できるようにしました。背景からナビゲーション メニューを実装するには、ログイン ユーザーの権限の違いによって、引き出されるナビゲーション メニューの効果が異なり、操作可能なインターフェイスも異なります。
バックグラウンド管理システムは 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 は第 1 レベルのナビゲーションのリストであり、実際にはルーティング機能はありません。 2 番目のレベルのメニューを切り替えるトリガーとして使用します。subList は実際に必要なルーティング情報です。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 { this.loging = false console.error('错误:', err) }) },
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 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> <el-menu> <el-menu-item> <i></i> <span>{{item.name}}</span> </el-menu-item> </el-menu> </p> </template> <script> 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>
<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. ページボタンのレベル制御に関しては、これを行うためのコマンドをカスタマイズできます。対応するルートのメタ オブジェクトに権限リストを入れているため、各ページで現在のユーザーが持つ権限に簡単に戻ることができます。 addRoutes メソッドが vue-router2 に追加されました。上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。
関連する推奨事項:
Vue 動的ルーティングの実装 (バックグラウンドがルートを渡し、フロントエンドがそれを取得してサイドバーを生成する)
Vue 属性 $route の params を介してパラメータを渡すvue-router+ nginxの非rootパスの設定方法
以上がaddRoutes は動的許可ルーティング メニューを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。