Vue에서 백그라운드 모니터링의 또 다른 사고방식 - 동적 루트의 실현과 최적화
전언
올해 초에 디킨에서 Vue 동적 렌더링 루트의 실현을 기록하는 글을 발표했는데, 현재 코드는 끊임없는 Review를 거치고 있다.
현재 이전의 실현 방법을 완전히 최적화하여 코드량이 많이 감소하고 논리가 더욱 간단하며 동시에 더욱 안정적이다
demo는github에 배치되었습니다. 환영합니다~~vue-element-asyncLogin, 당신의 start는 나의 동력입니다!
감권-전단 루트 VS 감권-동적 루트
전단 루트 감권은 vue-element-admin을 이해한 적이 있다면 전단 루트 감권 방안은 완전히 실행할 수 있고 사고방식이 뚜렷하며 난이도가 적당하며 프로젝트에서 충분히 사용할 수 있다고 믿는다. 그러면 상대적으로 동적 루트의 장점은 어디에 있는가?
은 더욱 사용하기 좋고 원가가 낮으며 프로그래머들도 996(안개)를 쓰지 않는다. 그러나 권한 등급이 많고 비교적 큰 프로젝트에 대해 이 감권 루트를 유지하는 것은 의심할 여지없이 큰 프로젝트이다. 그리고 빈번한 변경에 대한 수요에 직면하면 버그가 더욱 빈번해지고 전방 엔지니어의 작업량이 크게 증가한다.이럴 때는 전단 감권이 더 이상 좋은 방안이 아닌 것 같다생각을 실현하다
라우팅 정보는 모두 Vuex에 맡기고 localStorage에서 벗어나지 않아 시스템의 안정성을 높인다
기본 라우팅 구성
구체적 실현 방향
router/router.js
// ......
//
export const StaticRouterMap = [
{
path: '/login',
component: login,
meta: { title: ' ' },
hidden: true
},
{
path: '/user',
component: userLogin,
redirect: '/user/userlogin',
name: 'user',
hidden: true,
children: [
{
path: 'userLogin',
component: () => import('@/views/userLogin/components/login'),
meta: { title: ' ' }
},
{
path: 'userRegistry',
component: () => import('@/views/userLogin/components/registry'),
meta: { title: ' ' }
}
]
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
name: 'dashboard',
children: [
{
path: 'dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: ' ', icon: 'dashboard', affix: true }
}
]
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
}
]
export default new Router({
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes: StaticRouterMap
})
백엔드 학생과 맞춤형 루트 구조(이하 json)
백엔드는 현재 사용자 권한에 따라 루트 구조의 전단으로 동적 되돌아갈 것입니다. 더 이상 권한 문제를 고려할 필요가 없습니다.
[{
"id": 1,
"name": "Nested",
"code": null,
"description": null,
"url": "/nested",
"generatemenu": 0,
"sort": 0,
"parentId": null,
"permName": null,
"redirect": "/nested/menu1",
"title": "Nested",
"icon": "nested",
"children": [{
"id": 2,
"name": "Menu1",
"code": null,
"description": null,
"url": "menu1",
"generatemenu": 0,
"sort": 0,
"parentId": 1,
"permName": null,
"redirect": "",
"title": "Menu1",
"icon": "menu1",
"children": [{
"id": 4,
"name": "Menu1-1",
"code": null,
"description": null,
"url": "menu1-1",
"generatemenu": 0,
"sort": 0,
"parentId": 2,
"permName": null,
"redirect": "",
"title": "Menu1-1",
"icon": "",
"children": null
}, {
"id": 5,
"name": "Menu1-2",
"code": null,
"description": null,
"url": "menu1-2",
"generatemenu": 0,
"sort": 0,
"parentId": 2,
"permName": null,
"redirect": "",
"title": "Menu1-2",
"icon": "",
"children": null
}]
}, {
"id": 3,
"name": "Menu2",
"code": null,
"description": null,
"url": "menu2",
"generatemenu": 0,
"sort": 0,
"parentId": 1,
"permName": null,
"redirect": "",
"title": "Menu2",
"icon": "menu2",
"children": null
}]
}]
백엔드 초기 라우팅 데이터를 사용 가능한 데이터로 확인
물론 이것은 직접적으로 렌더링 루트에 사용되는 것이 아니라 우리가 원하는 데이터로 귀속 처리를 해야 한다
router/_import
export default file => {
return map[file] || null
}
const map = {
Nested: () => import('@/views/layout/Layout'),
Menu1: () => import('@/views/nested/menu1/index'),
'Menu1-1': () => import('@/views/nested/menu1/menu1-1'),
'Menu1-2': () => import('@/views/nested/menu1/menu1-2')
}
백엔드 원본 라우팅 데이터 처리
../utils/addRouter
귀속 기록은 이전 버전의 귀속 삭제보다 안정적이고 코드량도 적다
import _import from '../router/_import' //
/**
*
* @param {Array} routerlist
* @returns
*/
export function addRouter(routerlist) {
const router = []
routerlist.forEach(e => {
let e_new = {
path: e.url,
name: e.name,
component: _import(e.name)
}
if (e.children) {
e_new = Object.assign({}, e_new, { children: addRouter(e.children) })
}
if (e.redirect) {
e_new = Object.assign({}, e_new, { redirect: e.redirect })
}
if (e.generatemenu == 0) {
e_new = Object.assign({}, e_new, { hidden: true })
}
if (e.icon !== '' && e.title !== '') {
e_new = Object.assign({}, e_new, {
meta: { title: e.title, icon: e.icon }
})
} else if (e.title !== '' && e.icon === '') {
e_new = Object.assign({}, e_new, { meta: { title: e.title }})
}
router.push(e_new)
})
return router
}
처리 후 라우팅
우리가 처리한 루트 뒤에는 기존의router와 연결해야 하며, 여기에는 수요에 따라 루트 처리 규칙을 수정해야 한다
[{
"name": "Nested",
"redirect": "/nested/menu1",
"children": [{
"name": "Menu1",
"children": [{
"name": "Menu1-1",
"children": null,
"path": "menu1-1",
"meta": {
"title": "Menu1-1"
}
}, {
"name": "Menu1-2",
"children": null,
"path": "menu1-2",
"meta": {
"title": "Menu1-2"
}
}],
"path": "menu1",
"meta": {
"title": "Menu1",
"icon": "menu1"
}
}, {
"name": "Menu2",
"children": null,
"path": "menu2",
"component": null,
"meta": {
"title": "Menu2",
"icon": "menu2"
}
}],
"path": "/nested",
"meta": {
"title": "Nested",
"icon": "nested"
}
}]
(핵심) 결합 라우팅
이상은 모두 준비 작업입니다.
와 백엔드에서 되돌아오는
를 연결하기 위해서입니다.이 부분 코드도 최적화의 핵심이다
import router from './router'
import store from './store'
import { getToken, removeToken } from './utils/auth'
import NProgress from 'nprogress' // Progress
import 'nprogress/nprogress.css' // Progress
import { Message } from 'element-ui'
import { getRouter } from './api/login'
import { addRouter } from './utils/addRouter'
const whiteList = ['/login']
var data = false // demo , vuex
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
// cookice
if (to.path !== '/login') {
if (data) {
// data true,
next()
} else {
// data false, ,
gotoRouter(to, next)
}
} else {
Message({ message: ' ', type: 'info' })
next('/')
}
} else {
data = false
if (whiteList.indexOf(to.path) !== -1) {
//
next()
} else {
if (to.path !== '/login') {
// , 404
// next(`/login?redirect=${to.path}`)
next('/login')
} else {
next()
}
}
}
})
router.afterEach(() => {
NProgress.done() // Progress
})
function gotoRouter(to, next) {
getRouter(store.getters.token) //
.then(res => {
console.log(' ', res.data.data)
const asyncRouter = addRouter(res.data.data) //
// , , 404 .
asyncRouter.push({ path: '*', redirect: '/404', hidden: true })
return asyncRouter
})
.then(asyncRouter => {
router.addRoutes(asyncRouter) // vue-router addRouter
data = true //
store.dispatch('setRouterList', asyncRouter) // vuex
store.dispatch('GetInfo')
next({ ...to, replace: true }) // hack addRoutes
})
.catch(e => {
console.log(e)
removeToken()
})
}
Vuex 내부 논리
import { StaticRouterMap } from '../../router/index'
state: {
//.....
RouterList: [] //
},
mutations: {
set_router: (state, RouterList) => {
state.RouterList = RouterList
}
},
action: {
//
setRouterList({ commit }, routerList) {
commit('set_router', StaticRouterMap.concat(routerList)) //
},
}
이전의 논리에 비해 훨씬 간단하다
사이드바의 응용 루트 주소 수정
주의해야 할 것은addRoutes를 통해 통합된 루트는
this.$router.options.routes
에서 얻을 수 없기 때문에 가져온 루트를 this.$router.options.routes
에 연결해야 한다는 것이다.마지막으로 렌더링된 사이드바 부분의 코드를 수정합니다
src\views\layout\components\Sidebar\index.vue
computed: {
// ....
routes() {
return this.$store.getters.routerList
},
// ....
}
저는 간단한 demo vue-element-async Login을 정성껏 준비했습니다. 체험을 환영합니다. 도움이 된다면 스타트를 아끼지 마세요.
전재 대상:https://juejin.im/post/5caeb3756fb9a068967791b3
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.