vue+addRouters動的ルーティングメニューの実装
42840 ワード
ダイナミックルーティングという機能は、実は簡単でも簡単で、難しいと言っても少し難しいです.上コードloginコンポーネント
ページのリフレッシュ後の空白を防ぐために、もう一つの操作があります:App.vue
これで大功を成し遂げた.ルーティングフォーマットを処理するブロックは業務と強い関連性があるが、論理は大きく異なる:1、バックエンドが直接処理したルーティングリストに戻ると、みんな喜んで、直接使えばいい.2,バックエンドがフロントエンドに戻るのが各ルーティング間の関係であれば,フロントエンド自身が必要なルーティングリストに変換する必要がある.しかしフロントエンドは,各層のルーティング間のつながりを明らかにすれば,処理は難しくない.3,フロントエンドで必ず知る各ルート関係データ各レベルのルーティングid 各レベルのルーティングのname 各レベルのルーティングpath 各レベルルーティングが属するlevel 各レベルルーティングicon 各レベルのルーティングのidに対応する属する親のid
//template style
<script>
import router from '@/router' //
import Layout from '@/layout' // 1
import Block from '@/layout/block' // 2,
const _import = require('@/router/import') //module.exports = file => () => import(`@/${file}/index.vue`) 。
export default {
data() {
return { //
roleId: '',
menuList: [],
menu: [],
topMenus: [],
leftMenus: [],
firstUrl: ''
}
},
created() { // 404 ,
router.options.routes = [
{
path: '/view/manager/login',
component: () => import('@/view/manager/login')
},
{
path: '/view/manager/404',
component: () => import('@/view/manager/404'),
hidden: true
}
]
},
methods: {
async getRole() { // Id, Id
try {
const res = await auth.privilege({
method: 'get',
roleId: this.roleId
})
console.log('role', res)
// ,
if (res.status === 0) {
const _res = res.result.menus
const permissions = res.result.permissions
const o = this.menuList
this.firstUrl = _res[0].menuUrl
for (var i = 0; i < _res.length; i++) {
var index = _res[i]
o[i] = {}
o[i].path = index.menuUrl
o[i].meta = {}
o[i].meta.title = index.menuName
o[i].meta.icon = index.menuIcon
o[i].parentMenuId = index.parentMenuId
o[i].menuId = index.menuId
o[i].moduleId = index.moduleId
if (index.menuLevel === 1) {
o[i].component = 'Layout'
o[i].redirect = ''
o[i].children = []
} else if (index.menuLevel === 2) {
o[i].component = 'Block'
o[i].redirect = ''
o[i].children = []
} else if (index.menuLevel === 3) {
o[i].component = index.menuUrl
} else if (index.menuLevel === 4) {
o[i].component = index.menuUrl
o[i].hidden = true
}
if (index.moduleId === 1010 && index.parentMenuId === 0) {
o[i].hidden = true
} else if (index.moduleId === 1013 && index.parentMenuId === 0) {
o[i].hidden = true
}
}
for (var j = 0; j < o.length; j++) {
var pindex = o[j]
for (var k = 0; k < o.length; k++) {
var cindex = o[k]
if (cindex.parentMenuId === pindex.menuId) {
pindex.children.push(cindex)
pindex.redirect = pindex.children[0].path
}
}
}
o.forEach(item => {
if (item.parentMenuId === 0) {
this.menu.push(item)
}
if (item.parentMenuId === 0 && item.moduleId === 1010) {
this.topMenus.push(item)
}
if (item.parentMenuId === 0 && item.moduleId === 1013) {
this.topMenus.push(item)
}
})
// , sessionStorage
sessionStorage.setItem('permissions', JSON.stringify(permissions))
sessionStorage.setItem('routerMenus', JSON.stringify(this.menu))
sessionStorage.setItem('routerTopMenus', JSON.stringify(this.topMenus))
var routes = filterAsyncRouter(this.menu)
routes.push({
path: '*',
redirect: '/view/manager/404',
hidden: true
})
//
routes.forEach(item => {
router.options.routes.push(item)
})
// ,
router.addRoutes(routes)
// vuex
this.$store.dispatch('user/getPermissions', permissions)
this.$store.dispatch('user/getMenus', routes)
this.$store.dispatch('user/getTopMenus', this.topMenus)
this.$router.push(this.firstUrl)
} else {
this.$message({
message: res.msg,
type: 'warning'
})
}
} catch (err) {
console.log(err)
this.buttonLoading = false
this.$message({
message: err.data.msg ? err.data.msg : ' ',
type: 'warning'
})
}
}
}
}
//
function filterAsyncRouter(asyncRouterMap) {
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'Layout') { // Layout
route.component = Layout
} else if (route.component === 'Block') { // Block
route.component = Block
} else {
route.component = _import(route.path.substring(1, route.path.length))
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
</script>
ページのリフレッシュ後の空白を防ぐために、もう一つの操作があります:App.vue
//template style
<script>
import Layout from '@/layout'
import Block from '@/layout/block'
import router from './router'
const _import = require('@/router/import')
export default {
// sessionStorage
created() {
const userInfo = JSON.parse(sessionStorage.getItem('userInfo'))
const routerMenus = JSON.parse(sessionStorage.getItem('routerMenus'))
const routerTopMenus = JSON.parse(sessionStorage.getItem('routerTopMenus'))
const permissions = JSON.parse(sessionStorage.getItem('permissions'))
if (routerMenus && this.$store.state.user.menus.length === 0) {
this.$store.dispatch('user/getUserInfo', userInfo)
this.$store.dispatch('user/getMenus', routerMenus)
this.$store.dispatch('user/getTopMenus', routerTopMenus)
this.$store.dispatch('user/getPermissions', permissions)
var routes = filterAsyncRouter(routerMenus)
routes.push({
path: '*',
redirect: '/view/manager/404',
hidden: true
})
//
//
routes.forEach(item => {
router.options.routes.push(item)
})
//
router.addRoutes(routes)
}
}
}
function filterAsyncRouter(asyncRouterMap) {
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
if (route.component === 'Layout') {
route.component = Layout
} else if (route.component === 'Block') {
route.component = Block
} else {
route.component = _import(route.path.substring(1, route.path.length))
}
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
</script>
これで大功を成し遂げた.ルーティングフォーマットを処理するブロックは業務と強い関連性があるが、論理は大きく異なる:1、バックエンドが直接処理したルーティングリストに戻ると、みんな喜んで、直接使えばいい.2,バックエンドがフロントエンドに戻るのが各ルーティング間の関係であれば,フロントエンド自身が必要なルーティングリストに変換する必要がある.しかしフロントエンドは,各層のルーティング間のつながりを明らかにすれば,処理は難しくない.3,フロントエンドで必ず知る各ルート関係データ