做爰高潮a片〈毛片〉,尤物av天堂一区二区在线观看,一本久久A久久精品VR综合,添女人荫蒂全部过程av

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載

來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 22:28:43
文檔

vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載

vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載:此案例主要實(shí)現(xiàn)了一個功能是,在vue實(shí)例首次運(yùn)行時,在加載了login和404兩個路由規(guī)則,登錄成功后,根據(jù)登錄用戶角色權(quán)限獲取該角色相應(yīng)菜單權(quán)限,生成新的路由規(guī)則添加進(jìn)去。 做過后臺管理系統(tǒng)都一定做過這個功能,在對菜單權(quán)限進(jìn)行粗粒度權(quán)限控制的時候,通
推薦度:
導(dǎo)讀vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載:此案例主要實(shí)現(xiàn)了一個功能是,在vue實(shí)例首次運(yùn)行時,在加載了login和404兩個路由規(guī)則,登錄成功后,根據(jù)登錄用戶角色權(quán)限獲取該角色相應(yīng)菜單權(quán)限,生成新的路由規(guī)則添加進(jìn)去。 做過后臺管理系統(tǒng)都一定做過這個功能,在對菜單權(quán)限進(jìn)行粗粒度權(quán)限控制的時候,通

此案例主要實(shí)現(xiàn)了一個功能是,在vue實(shí)例首次運(yùn)行時,在加載了login和404兩個路由規(guī)則,登錄成功后,根據(jù)登錄用戶角色權(quán)限獲取該角色相應(yīng)菜單權(quán)限,生成新的路由規(guī)則添加進(jìn)去。

做過后臺管理系統(tǒng)都一定做過這個功能,在對菜單權(quán)限進(jìn)行粗粒度權(quán)限控制的時候,通過角色獲取菜單后,異步生成菜單,所以一開始拿到需求的時候,我也以為這和平常的沒什么不同,不過做起來就發(fā)現(xiàn)了很多問題,

1.vue-router的實(shí)例,在new vue實(shí)例的時候,就加載了,且必須加載,這個時候,登錄路由一定要加載,可是這個時候沒有登錄,無法確定權(quán)限
2.路由規(guī)則與菜單的同步

解決思路演化,菜單和路由同步,肯定是采用了vuex,一開始的思路的是,在一開始,就把所有的路由規(guī)則加載,然后在登錄的時候,取得權(quán)限路由,對比兩個路由,通過修改修改一個權(quán)限字段來隱藏菜單,如果在后臺頁面添加了新菜單規(guī)則,路由是按模塊加載的不同的文件,這時對路由的文件進(jìn)行新的讀寫,雖然可以解決問題,但是如果手動在瀏覽器地址上路由,依然可以訪問,所以在路由的全局鉤子上還要做攔截。

這個解決方案雖然解決,但是顯的比較復(fù)雜,于是就想需找新的方法,重新瀏覽官方api,發(fā)現(xiàn)在2.2.0以后,官方新增了api,addRoutes,專門針對服務(wù)端渲染路由,那么這下問題就比較簡單了,下面列出實(shí)現(xiàn)代碼。以下代碼不能直接復(fù)用,需要根據(jù)實(shí)際情況修改,只是提供思路

app.js

let permission = JSON.parse(window.sessionStorage.getItem('permission')) 
if (permission) { 
 store.commit(ADD_MENU, permission) 
 router.addRoutes(store.state.menu.items) 
} 
router.beforeEach((route, redirect, next) => { 
 if (state.app.device.isMobile && state.app.sidebar.opened) { 
 store.commit(TOGGLE_SIDEBAR, false) 
 } 
 if (route.path === '/login') { 
 window.sessionStorage.removeItem('user') 
 window.sessionStorage.removeItem('permission') 
 store.commit(ADD_MENU, []) 
 } 
 let user = JSON.parse(window.sessionStorage.getItem('user')) 
 if (!user && route.path !== '/login') { 
 next({ path: '/login' }) 
 } else { 
 if (route.name) { 
 next() 
 } else { 
 next({ path: '/nofound' }) 
 } 
 } 
}) 

登錄的組件login.vue

<template> 
 <el-form :model="ruleForm2" :rules="rules2" ref="ruleForm2" label-position="left" label-width="0px" 
 class="demo-ruleForm login-container"> 
 <h3 class="title">系統(tǒng)登錄</h3> 
 <el-form-item prop="account"> 
 <el-input type="text" v-model="ruleForm2.account" auto-complete="off" placeholder="賬號"></el-input> 
 </el-form-item> 
 <el-form-item prop="checkPass"> 
 <el-input type="password" v-model="ruleForm2.checkPass" auto-complete="off" placeholder="密碼"></el-input> 
 </el-form-item> 
 <el-checkbox v-model="checked" checked class="remember">記住密碼</el-checkbox> 
 <el-form-item style="width:100%;"> 
 <el-button type="primary" style="width:100%;" @click.native.prevent="handleSubmit2" :loading="logining">登錄 
 </el-button> 
 <!--<el-button @click.native.prevent="handleReset2">重置</el-button>--> 
 </el-form-item> 
 </el-form> 
</template> 
 
<script> 
 import NProgress from 'nprogress' 
 import { mapActions, mapGetters } from 'vuex' 
 export default { 
 data () { 
 return { 
 logining: false, 
 ruleForm2: { 
 account: 'admin', 
 checkPass: '123456' 
 }, 
 rules2: { 
 account: [ 
 {required: true, message: '請輸入賬號', trigger: 'blur'} 
 // { validator: validaePass } 
 ], 
 checkPass: [ 
 {required: true, message: '請輸入密碼', trigger: 'blur'} 
 // { validator: validaePass2 } 
 ] 
 }, 
 checked: true 
 } 
 }, 
 computed: { 
 ...mapGetters([ 
 'menuitems', 
 'isLoadRoutes' 
 // ... 
 ]) 
 }, 
 methods: { 
 handleReset2 () { 
 this.$refs.ruleForm2.resetFields() 
 }, 
 handleSubmit2 (ev) { 
 this.$refs.ruleForm2.validate((valid) => { 
 if (valid) { 
 this.logining = true 
 NProgress.start() 
 let loginParams = {loginName: this.ruleForm2.account, password: this.ruleForm2.checkPass} 
 this.$http.post('/api/privilege/user/login', loginParams).then(resp => { 
 this.logining = false 
 NProgress.done() 
 let {message, data} = resp.data 
 
 if (message === 'fail') { 
 this.$notify({ 
 title: '錯誤', 
 message: message, 
 type: 'error' 
 }) 
 } else { 
 window.sessionStorage.setItem('user', JSON.stringify(data.user)) 
 window.sessionStorage.setItem('permission', JSON.stringify(data.permission)) 
 this.addMenu(data.permission) 
 if (!this.isLoadRoutes) { 
 this.$router.addRoutes(this.menuitems) 
 this.loadRoutes() 
 } 
 this.$router.push('/system/office') 
 } 
 }) 
 } else { 
 console.log('error submit!!') 
 return false 
 } 
 }) 
 }, 
 
 ...mapActions([ 
 'addMenu', 
 'loadRoutes' 
 ]) 
 } 
 } 
 
</script> 
 
<style lang="scss" scoped> 
 .login-container { 
 /*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/ 
 -webkit-border-radius: 5px; 
 border-radius: 5px; 
 -moz-border-radius: 5px; 
 background-clip: padding-box; 
 margin-bottom: 20px; 
 background-color: #F9FAFC; 
 margin: 180px auto; 
 border: 2px solid #8492A6; 
 width: 350px; 
 padding: 35px 35px 15px 35px; 
 
 .title { 
 margin: 0px auto 40px auto; 
 text-align: center; 
 color: #505458; 
 } 
 
 .remember { 
 margin: 0px 0px 35px 0px; 
 } 
 
 } 
</style> 

關(guān)鍵點(diǎn)解釋

computed: { 
 ...mapGetters([ 
 'menuitems', 
 'isLoadRoutes' 
 // ... 
 ]) 
 }, 

這里是從vuex取得兩個對象,menuitems是菜單對象,isLoadRoutes是用來判斷是否是第一次登錄,用來排除重復(fù)加載路由規(guī)則

...mapActions([ 
 'addMenu', 
 'loadRoutes' 
 ]) 

這里是從vuex取得兩個方法,一個是添加菜單,一個更改loadRoutes的值

this.$router.addRoutes(this.menuitems) 

這是關(guān)鍵api,動態(tài)的向router實(shí)例中添加路由規(guī)則

menu模塊的state與mutations

const state = { 
 items: [ 
 ], 
 isLoadRoutes: false 
} 
 
const mutations = { 
 [types.EXPAND_MENU] (state, menuItem) { 
 if (menuItem.index > -1) { 
 if (state.items[menuItem.index] && state.items[menuItem.index].meta) { 
 state.items[menuItem.index].meta.expanded = menuItem.expanded 
 } 
 } else if (menuItem.item && 'expanded' in menuItem.item.meta) { 
 menuItem.item.meta.expanded = menuItem.expanded 
 } 
 }, 
 [types.ADD_MENU] (state, menuItems) { 
 if (menuItems.length === 0) { 
 state.items = [] 
 } else { 
 generateMenuItems(state.items, menuItems) 
 } 
 }, 
 [types.LOAD_ROUTES] (state) { 
 state.isLoadRoutes = !state.isLoadRoutes 
 } 
} 

路由配置文件router.js

import Vue from 'vue' 
import Router from 'vue-router' 
import menuModule from 'vuex-store/modules/menu' 
Vue.use(Router) 
 
export default new Router({ 
 mode: 'hash', // Demo is living in GitHub.io, so required! 
 linkActiveClass: 'is-active', 
 scrollBehavior: () => ({ y: 0 }), 
 routes: [ 
 { 
 path: '/login', 
 component: require('../Login.vue'), 
 meta: { 
 expanded: false, 
 show: false 
 }, 
 name: 'Login' 
 }, 
 { 
 path: '/', 
 component: require('../views/Home.vue'), 
 meta: { 
 expanded: false, 
 show: false 
 }, 
 children: [ 
 { path: '/nofound', component: require('../404.vue'), name: 'NOFOUND', meta: {show: false} } 
 ] 
 }, 
 ...generateRoutesFromMenu(menuModule.state.items) 
 ] 
}) 
 
// Menu should have 2 levels. 
function generateRoutesFromMenu (menu = [], routes = []) { 
 for (let i = 0, l = menu.length; i < l; i++) { 
 let item = menu[i] 
 if (item.path) { 
 routes.push(item) 
 } 
 } 
 return routes 
} 

vuex

import Vue from 'vue' 
import Vuex from 'vuex' 
import * as actions from './actions' 
import * as getters from './getters' 
 
import menu from './modules/menu' 
 
Vue.use(Vuex) 
 
const store = new Vuex.Store({ 
 strict: true, // process.env.NODE_ENV !== 'development', 
 actions, 
 getters, 
 modules: { 
 menu 
 }, 
 mutations: { 
 } 
}) 
 
export default store 

actions

export const addMenu = ({ commit }, menuItems) => { 
 if (menuItems.length > 0) { 
 commit(types.ADD_MENU, menuItems) 
 } 
} 
 
export const loadRoutes = ({ commit }) => { 
 commit(types.LOAD_ROUTES) 
} 

getters

const menuitems = state => state.menu.items 
const isLoadRoutes = state => state.menu.isLoadRoutes 
export { 
 menuitems, 
 isLoadRoutes 
} 

mutations_type.js

export const ADD_MENU = 'ADD_MENU' 
 
export const LOAD_ROUTES = 'LOAD_ROUTES' 

因?yàn)樯厦娴拇a不能直接運(yùn)行,再次梳理一下思路,

1.創(chuàng)建vue實(shí)例的時候,將vuex和vue-router加載,這個時候,vue-router只有登錄規(guī)則和404規(guī)則

2.vuex中state管理的狀態(tài)對象有,菜單對象menuitems,是否加載過路由loadRoutes ,并提供相應(yīng)的getters與actions當(dāng)然還有一些其他的,這里沒有列舉

3.然后在登錄組件中,登錄成功后,將服務(wù)端傳回來之后,調(diào)用actions更改state.menuitems,并且中間有格式化的過程,這個過程的代碼沒有貼出來,主要是由于不同的表涉和服務(wù)端返回的數(shù)據(jù)不一樣,,

4.然后調(diào)用addRoutes和actions更改已經(jīng)加載過路由的方法

5.然后為了防止用戶直接手動按f5刷新頁面,這個時候會重新構(gòu)建vue實(shí)例,而又沒有重新登錄,所以vuex里面的東西會清空,所以將登錄后的數(shù)據(jù)存放在sessionStroage中,在刷新頁面,重新構(gòu)建vue實(shí)例的時候,會有判斷

6.之后會渲染側(cè)邊欄組件,列出菜單,數(shù)據(jù)就可以根據(jù)state.menuitems來就可以了,我這里沒有貼我的,實(shí)際根據(jù)自己的需求來

后面有時間會在github上上傳完整代碼。

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載

vue-router+vuex addRoutes實(shí)現(xiàn)路由動態(tài)加載及菜單動態(tài)加載:此案例主要實(shí)現(xiàn)了一個功能是,在vue實(shí)例首次運(yùn)行時,在加載了login和404兩個路由規(guī)則,登錄成功后,根據(jù)登錄用戶角色權(quán)限獲取該角色相應(yīng)菜單權(quán)限,生成新的路由規(guī)則添加進(jìn)去。 做過后臺管理系統(tǒng)都一定做過這個功能,在對菜單權(quán)限進(jìn)行粗粒度權(quán)限控制的時候,通
推薦度:
標(biāo)簽: 加載 菜單 VUE
  • 熱門焦點(diǎn)

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 改则县| 鄂温| 湄潭县| 沾化县| 商城县| 蒙阴县| 南华县| 花莲县| 怀来县| 榆社县| 胶南市| 湟源县| 南开区| 武强县| 阳高县| 满洲里市| 固始县| 滕州市| 宜城市| 溆浦县| 河源市| 冷水江市| 新民市| 霍州市| 秀山| 垫江县| 封开县| 民权县| 宁夏| 嫩江县| 长治市| 资源县| 张家口市| 晋州市| 沙田区| 永靖县| 美姑县| 临颍县| 长沙县| 东辽县| 和政县|