Heim  >  Artikel  >  Web-Frontend  >  vue+vue-router+vuex-Betriebsberechtigungen

vue+vue-router+vuex-Betriebsberechtigungen

php中世界最好的语言
php中世界最好的语言Original
2018-05-14 13:58:243323Durchsuche

Dieses Mal werde ich Ihnen die Betriebsberechtigungen für Vue + Vue-Router + Vuex vorstellen. Was sind die Vorsichtsmaßnahmen für die Betriebsberechtigungen für Vue + Vue-Router + Vuex? Schauen Sie mal rein.

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 = ''
 }
}

AbfangurteilKein 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中文网其它相关文章!

推荐阅读:

react router4+redux控制路由权限步骤详解

v-bind与v-on使用案例详解

Vue表单类父子组件数据传递数据方法总结

Das obige ist der detaillierte Inhalt vonvue+vue-router+vuex-Betriebsberechtigungen. 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