Heim  >  Artikel  >  Web-Frontend  >  So verwenden Sie Vue, Vue-Router, Vuex und AddRoutes zur Berechtigungskontrolle

So verwenden Sie Vue, Vue-Router, Vuex und AddRoutes zur Berechtigungskontrolle

php中世界最好的语言
php中世界最好的语言Original
2018-06-01 11:45:021479Durchsuche

Dieses Mal zeige ich Ihnen, wie Sie Vue, Vue-Router, Vuex und AddRoutes zur Berechtigungskontrolle verwenden. Was sind die Vorsichtsmaßnahmen für die Verwendung von Vue, Vue-Router, Vuex und AddRoutes zur Berechtigungskontrolle? wie folgt Dies ist ein praktischer Fall, schauen wir ihn uns an.

Tutorial zur Berechtigungskontrolle basierend auf Vuex, Vue-Router, Vuex, die vollständige Codeadresse finden Sie unter https://github.com/ linrunzheng/vue- Permission-Control

Als nächstes simulieren wir den Prozess eines normalen Benutzers, der die Website öffnet, und gehen den gesamten Prozess Schritt für Schritt durch.

Öffnen Sie zunächst den lokalen Dienst localhost:8080. Wir wissen, dass wir nach dem Öffnen die Anmeldeseite aufrufen. Was ist also die Grundlage für die Beurteilung?

Das erste ist ein Token.

Benutzer, die nicht angemeldet sind, können das Token nicht erhalten. Für angemeldete Charaktere speichern wir das Token im lokalen oder seesionStorage. Daher können Sie anhand dessen erkennen, ob Sie sich anmelden müssen oder nicht ob aktuell ein Token vorhanden ist.

Um auf das Token zuzugreifen und unseren Betrieb zu erleichtern, kann es mit vuex kombiniert werden, um

/* state.js */
export default {
 get UserToken() {
 return localStorage.getItem('token')
 },
 set UserToken(value) {
 localStorage.setItem('token', value)
 }
}
/* mutation.js */
export default {
 LOGIN_IN(state, token) {
 state.UserToken = token
 },
 LOGIN_OUT(state) {
 state.UserToken = ''
 }
}

Abfangurteil

Kein Token Rufen Sie die Seite auf, für die Berechtigungen erforderlich sind: Weiterleitung zur Anmeldeseite

Da unsere Routen dynamisch bereitgestellt werden, einschließlich „ “ und 404, leiten wir auch zur Anmeldung weiter, wenn keine Route übereinstimmt

router.beforeEach((to, from, next) => {
 if (!store.state.UserToken) {
 if (
 to.matched.length > 0 &&
 !to.matched.some(record => record.meta.requiresAuth)
 ) {
 next()
 } else {
 next({ path: '/login' })
 }
 } 
})
Okay, jetzt öffnet der Benutzer localhost:8080 und der Standard-Übereinstimmungspfad ist ''. Zu diesem Zeitpunkt haben wir die Route noch nicht gemountet und haben kein Token, also kommen wir zum Anmelden.

Nach Eingabe des Benutzernamens und Passworts erfolgt ein Token-Trigger *commit('LOGIN_IN')* durch den Store, um den Token festzulegen.

Aber es gibt derzeit noch keine Route.

/* 初始路由 */
export default new Router({
 routes: [
 {
 path: '/login',
 component: Login
 }
 ]
})
/* 准备动态添加的路由 */
export const DynamicRoutes = [
 {
 path: '',
 component: Layout,
 name: 'container',
 redirect: 'home',
 meta: {
 requiresAuth: true,
 name: '首页'
 },
 children: [
 {
 path: 'home',
 component: Home,
 name: 'home',
 meta: {
  name: '首页'
 }
 }
 ]
 },
 {
 path: '/403',
 component: Forbidden
 },
 {
 path: '*',
 component: NotFound
 }
]
Wir müssen in den Hintergrund gehen, um Berechtigungen basierend auf dem Token des aktuellen Benutzers zu erhalten.

Da Berechtigungen ziemlich viel Logik beinhalten, wurde vuex ein Berechtigungsmodul hinzugefügt, um Berechtigungen zu verwalten.

Um festzustellen, ob eine Routenliste vorhanden ist, müssen Sie zur Beurteilung eine Status-Berechtigungsliste im Berechtigungsmodul von vuex speichern. Wenn die Berechtigungsliste nicht null ist, bedeutet dies, dass bereits eine Route vorhanden ist. Wenn es nicht existiert, müssen wir arbeiten.

router.beforeEach((to, from, next) => {
 if (!store.state.UserToken) {
 ...
 } else {
 /* 现在有token了 */
 if (!store.state.permission.permissionList) {
 /* 如果没有permissionList,真正的工作开始了 */
 store.dispatch('permission/FETCH_PERMISSION').then(() => {
 next({ path: to.path })
 })
 } else {
 if (to.path !== '/login') {
 next()
 } else {
 next(from.fullPath)
 }
 }
 }
})
Sehen wir uns an, was store.dispatch('permission/FETCH_PERMISSION') macht

actions: {
 async FETCH_PERMISSION({ commit, state }) {
 /* 获取后台给的权限数组 */
 let permissionList = await fetchPermission()
 /* 根据后台权限跟我们定义好的权限对比,筛选出对应的路由并加入到path=''的children */
 let routes = recursionRouter(permissionList, dynamicRouter)
 let MainContainer = DynamicRoutes.find(v => v.path === '')
 let children = MainContainer.children
 children.push(...routes)
 /* 生成左侧导航菜单 */
 commit('SET_MENU', children)
 setDefaultRoute([MainContainer])
 /* 初始路由 */
 let initialRoutes = router.options.routes
 /* 动态添加路由 */
 router.addRoutes(DynamicRoutes)
 /* 完整的路由表 */
 commit('SET_PERMISSION', [...initialRoutes, ...DynamicRoutes])
 }
}
Erst ruft „await fetchPermission()“ das vom Hintergrund vorgegebene Berechtigungsarray ab wie folgt

{
 "code": 0,
 "message": "获取权限成功",
 "data": [
 {
 "name": "订单管理",
 "children": [
 {
  "name": "订单列表"
 },
 {
  "name": "生产管理",
  "children": [
  {
  "name": "生产列表"
  }  
  ]
 },
 {
  "name": "退货管理"
 }
 ]
 }
 ]
}
Zweitens, basierend auf dem von uns geschriebenen Routenarray, vergleichen und filtern, um die Route zu erhalten, die wir wollen

/* 这里是我们写好的需要权限判断的路由 */
const dynamicRoutes = [
 {
 path: '/order',
 component: Order,
 name: 'order-manage',
 meta: {
 name: '订单管理'
 },
 children: [
 {
 path: 'list',
 name: 'order-list',
 component: OrderList,
 meta: {
  name: '订单列表'
 }
 },
 {
 path: 'product',
 name: 'product-manage',
 component: ProductManage,
 meta: {
  name: '生产管理'
 },
 children: [
  {
  path: 'list',
  name: 'product-list',
  component: ProductionList,
  meta: {
  name: '生产列表'
  }
  },
  {
  path: 'review',
  name: 'review-manage',
  component: ReviewManage,
  meta: {
  name: '审核管理'
  }
  }
 ]
 },
 {
 path: 'returnGoods',
 name: 'return-goods',
 component: ReturnGoods,
 meta: {
  name: '退货管理'
 }
 }
 ]
 }
]
export default dynamicRoutes
Zum Vergleich habe ich eine

rekursive Funktion geschrieben, Wenn wir zum Vergleich name und meta .name verwenden, können wir das gewünschte Ergebnis basierend auf dieser Funktion erhalten.

/**
 *
 * @param {Array} userRouter 后台返回的用户权限json
 * @param {Array} allRouter 前端配置好的所有动态路由的集合
 * @return {Array} realRoutes 过滤后的路由
 */
export function recursionRouter(userRouter = [], allRouter = []) {
 var realRoutes = []
 allRouter.forEach((v, i) => {
 userRouter.forEach((item, index) => {
 if (item.name === v.meta.name) {
 if (item.children && item.children.length > 0) {
  v.children = recursionRouter(item.children, v.children)
 }
 realRoutes.push(v)
 }
 })
 })
 return realRoutes
}
Nachdem Sie das gefilterte Array erhalten haben, fügen Sie es den untergeordneten Elementen mit dem Pfad ''

{
 path: '',
 component: Layout,
 name: 'container',
 redirect: 'home',
 meta: {
 requiresAuth: true,
 name: '首页'
 },
 children: [
 {
 path: 'home',
 component: Home,
 name: 'home',
 meta: {
  name: '首页'
 }
 },
 <!-- 将上面得到的东西加入到这里 -->
 ...
 ]
 }
At hinzu Dieses Mal, path Die untergeordneten Elemente von '' sind unser Navigationsmenü auf der linken Seite, das zur späteren Verwendung in der SeitenleisteMenu des Status gespeichert wird. Nach dem Hinzufügen zu untergeordneten Elementen können DynamicRoutes zur Route hinzugefügt werden.

/* 动态添加路由 */
router.addRoutes(DynamicRoutes)
 /* 初始路由 */
let initialRoutes = router.options.routes
/* 合并起来,就是完整的路由了 */
commit('SET_PERMISSION', [...initialRoutes, ...DynamicRoutes])
Nachdem die Route hinzugefügt wurde, dh der Aktionsvorgang abgeschlossen ist, können Sie next({ path: to.path }) in action.then aufrufen, um die Route einzugeben. Bitte beachten Sie hier die Parameter Als nächstes müssen die Routing-Informationen der eingegebenen Seite übergeben werden, da nach dem nächsten Übergeben des Parameters die aktuell einzugebende Route gelöscht und die dem Parameter entsprechende Route eingegeben wird. Dies ist jedoch dieselbe Hauptsächlich, um sicherzustellen, dass addRoutes wirksam wird.

Nachdem wir das Routing eingegeben haben, müssen wir mit der Generierung des linken Menüs beginnen. Jetzt müssen wir nur noch das Menü rekursiv generieren. Für rekursives Routing müssen wir es noch selbst kapseln. Der Kern hier ist der Name der Komponente. Wenn die Komponente untergeordnete Elemente enthält, durchlaufen Sie erneut das Routing der gesamten Baumstruktur.

<template>
 <p class="menu-container">
 <template v-for="v in menuList">
 <el-submenu :index="v.name" v-if="v.children&&v.children.length>0" :key="v.name">
 <template slot="title">
  <i class="iconfont icon-home"></i>
  <span>{{v.meta.name}}</span>
 </template>
 <el-menu-item-group>
  <my-nav :menuList="v.children"></my-nav>
 </el-menu-item-group>
 </el-submenu>
 <el-menu-item :key="v.name" :index="v.name" @click="gotoRoute(v.name)" v-else>
 <i class="iconfont icon-home"></i>
 <span slot="title">{{v.meta.name}}</span>
 </el-menu-item>
 </template>
 </p>
</template>
<script>
export default {
 name: 'my-nav',
 props: {
 menuList: {
 type: Array,
 default: function() {
 return []
 }
 }
 },
 methods: {
 gotoRoute(name) {
 this.$router.push({ name })
 }
 }
}
</script>
Nach dem Aktualisieren der Seite gibt es laut unserem Router.beforeEach-Urteil ein Token, aber keine Berechtigungsliste. Wir werden die Aktion erneut auslösen, um die Route zu erhalten, sodass kein Grund zur Sorge besteht. Der aktive Effekt des Navigationsmenüs verschwindet jedoch. Allerdings haben wir den Schlüssel von el-menu-item auf den Namen der Route gesetzt, sodass wir nach der Aktualisierung nur den Namen der aktuellen Route el-menu default-active in afterEach zuweisen müssen. Auf die gleiche Weise kann die

Breadcrumb-Navigation implementiert werden, indem alle übereinstimmenden Routen in der AfterEach-Phase abgerufen werden.

if (!store.state.permission.permissionList) {
 store.dispatch('permission/FETCH_PERMISSION').then(() => {
 next({ path: to.path })
 })
} 
...
router.afterEach((to, from, next) => {
 var routerList = to.matched
 store.commit('setCrumbList', routerList)
 store.commit('permission/SET_CURRENT_MENU', to.name)
})

退出登陆后,需要刷新页面,因为我们是通过addRoutes添加的,router没有deleteRoutes这个api,所以清除token,清除permissionList等信息,刷新页面是最保险的。

最后还有一点,每次请求得带上token, 可以对axios封装一下来处理

var instance = axios.create({
 timeout: 30000,
 baseURL
})
// 添加请求拦截器
instance.interceptors.request.use(
 function(config) {
 // 请求头添加token
 if (store.state.UserToken) {
 config.headers.Authorization = store.state.UserToken
 }
 return config
 },
 function(error) {
 return Promise.reject(error)
 }
)
/* axios请求二次封装 */
instance.get = function(url, data, options) {
 return new Promise((resolve, reject) => {
 axios
 .get(url, data, options)
 .then(
 res => {
  var response = res.data
  if (response.code === 0) {
  resolve(response.data)
  } else {
  Message.warning(response.message)
  /* reject(response.message) */
  }
 },
 error => {
  if (error.response.status === 401) {
  Message.warning({
  message: '登陆超时,请重新登录'
  })
  store.commit('LOGIN_OUT')
  window.location.reload()
  } else {
  Message.error({
  message: '系统异常'
  })
  }
  reject(error)
 }
 )
 .catch(e => {
 console.log(e)
 })
 })
}
export default instance

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

使用JS判断字符串中包含内容方法总结

Angular+RouterLink做出不同的花式跳转

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Vue, Vue-Router, Vuex und AddRoutes zur Berechtigungskontrolle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn