## vue鑒權的實現
### 路由的動態注入
#### 遞歸遍歷路由
**靜態路由**
```
// 靜態路由
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
})
```
#### 權限數據
```
[{
"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
}]
}]
```
#### 組件
異步加載
```
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')
}
```
#### 遞歸遍歷路由
```
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
}
```
#### 處理后的路由
```
[{
"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)) // 進行路由拼接并存儲
},
}
```
#### 掛載路由
```
computed: {
// ....
routes() {
return this.$store.getters.routerList
},
// ....
}
```
- css用法技巧
- 陰影被后面div遮擋
- 繪制一個三角形
- 圖像的灰白處理
- 一切居中
- 禁用鼠標事件
- 模糊文本
- 字體省略號
- 垂直居中
- box投影
- css動畫
- javaScript常見工具封裝
- 地址欄參數獲取
- 日期格式化
- Ajax
- scroll
- 緩動函數
- 事件綁定
- 阻止冒泡和默認行為
- 偽數組正常化
- 日期生成
- 拷貝
- javaScript基本知識
- javaScript基本知識
- javascript常見代碼塊
- vue常見問題
- 獲取參數
- vue常見問題/vue混入
- v-html指令問題集錦
- 正則獲取html中所有的中文字符
- 時間格式化
- 監聽路由的變化
- vue移動端滑動事件
- vue移動端圖片點擊放大
- 打包后背景圖片404的問題
- webpack打包后部分樣式失效
- IE的兼容問題
- post請求后臺無法接受參數
- 驗證碼
- vue開啟Gzip報錯
- v-html修改樣式
- app.css文件過大
- vue中中使用iframe
- babel對es6編譯不徹底 出現ie不兼容的問題
- vue單頁應用優化
- 吸頂問題
- 跨域session無法共享
- 登陸返回上一頁
- axois中使用delete數據傳遞問題
- 監聽數組對象數組中的屬性
- webpack
- webpack基本使用
- webpack打包刪除注釋
- js插件
- 輪播圖
- 面向對象模板
- 左滑右滑
- 存儲
- appcan
- appcan
- js深入研究
- 數組的參數傳遞問題
- 采用jquery的方法載入公共頁面后出現閃爍的問題
- html拼接無法綁定事件
- 吸頂問題
- async配合promise使用
- flutter
- 模擬器加載報錯
- 底部導航實現
- 模擬器出現錯誤
- flutter在idea下的快捷鍵
- flutter學習筆記
- 設計模式
- 觀察者模式
- nest
- nest基本說明
- nest錯誤處理
- vue高級
- 動態注入路由
- nest實戰
- 一項目準備
- window
- 端口進程被占
- mis包
- reactNative
- react-native-router-flux
- esLint
- eslint
- Cesium