vue addRoutes を使用して動的許可ルーティング メニューを実装する手順の詳細な説明

php中世界最好的语言
リリース: 2018-05-21 13:52:48
オリジナル
14338 人が閲覧しました

今回は、vue addRoutes を使用して動的パーミッション ルーティング メニューを実装する手順について詳しく説明します。vue 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 レベルのナビゲーションのリストです。実際には、第 1 レベルのナビゲーションには

ルーティング関数 がありません。 、これは セカンダリ メニュー を切り替えるための単なるトリガーです、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 <= 1) {
        this.$router.addRoutes(routes)
        // this.$router不是响应式的,所以手动将路由元注入路由对象
        this.$router.options.routes.push(routes)
       }
       this.$router.replace(&#39;/layout/index&#39;)
      }
     })
     .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 !== &#39;0008&#39;">
     <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 で次のコードを実行できます (追記: どこで更新しても 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. ページボタンのレベル制御に関しては、これを行うためのコマンドをカスタマイズできます。対応するルートのメタオブジェクトに権限リストを入れているため、各ページの現在のページで現在のユーザーが持つ権限に簡単に戻ることができます

カスタム手順については公式ドキュメントを参照してください

結論

作業が完了したら、vue-router2 に追加された addRoutes メソッドのおかげで、それ以外の場合は

この記事の事例を読んだ後はメソッドを習得したと思います。さらに興味深い情報については、注目してください。 PHP 中国語 Web サイトの他の関連記事へ!

推奨読書:

phpでカスタムの長さのランダムな文字列を生成する手順の詳細な説明

php画像のトリミングとサムネイルの使用方法の説明

以上がvue addRoutes を使用して動的許可ルーティング メニューを実装する手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!