vue-element-admin擼後臺實踐(一)
一個專案首先要解決的問題,同時也是核心的問題就是登陸和許可權的問題,vue-element-admin將路由和左邊側欄進行了繫結,所以我們要解決的就是根據不同的role,生成不同的路由,然後動態渲染不同的側邊欄,同時還要解決在後臺可以通過tree控制元件動態設定許可權的效果,所以,先擼一下整體實現思路:
首先要說一下,vue-element-admin是怎麼與後端進行互動的:使用者端有互動提交---->>呼叫api下的.js請求函式(有些請求函式我單獨放到service裡了)--->>呼叫untils下的request.js(封裝好的請求axiso)--->>獲取到後端返回的response--->>進行客戶端data渲染(後面我會細說一下request.js裡封裝的axiso)
1.登陸:當使用者完成登陸後,要實現兩個功能:一是:會向後端進行user_info的獲取,並把相關資訊寫入cookie中,以實現整個系統的一個角色繫結。二是進行頁面的跳轉
2.許可權:登陸後在permission.js中router.beforeEach方法中利用寫在請求頭裡的cookie向後端獲取menuList,然後利用vuex進行路由的拼接,最後通過router.addRouter掛載所計算好的路由並實現側邊欄的動態渲染
ok,下面擼一下具體的實現操作:
1,login頁面的click事件中寫:
handleLogin() {
this.$refs.loginForm.validate(async valid => { //進行登陸驗證
if (valid) { //驗證通過
this.loading = true
this.logins='登入中...'
const { username, password } = this.loginForm
try { //像後端獲取user_info並儲存到cookie中
const res = await login({ user_name: username, passwd: password })
setUserInfo(res.data) //user_info儲存到cookie中
this.loading = false
this.logins='登入'
this.$router.push({ path: '/' }) //跳轉到首頁
} catch (e) {
this.loading = false
this.logins='登入'
}
} else {
console.log('error submit!!')
return false
}
})
}
其中setUserInfo()方法在utils下的auth.js,其中這裡面可以寫一些cookie的相關函式,並export出去,以供複用
// 設定Role_id
export function setRoleId(roleId) {
return Cookies.set(RoleKey, roleId)
} //這裡只寫一個,其他的set方法都類似於此
// 儲存使用者資訊
export function setUserInfo(user) {
const { role_id, agent_id, user_name,
agent_name, province_id, level, price, city_name,
city_ip
} = user
setRoleId(role_id)
setAgentId(agent_id)
setUserName(user_name)
setAgentName(agent_name)
setProvinceId(province_id)
setLevel(level)
setPrice(price / 100)
setCityName(city_name)
setCityIp(city_ip)
}
// 清除使用者資訊
export function removeUserInfo() {
removeRoleId()
removeAgentId()
removeUserName()
removeAgentName()
removeProvinceId()
removeLevel()
removePrice()
removeCityName()
removeCityIp()
}
2.然後在在permission.js中router.beforeEach,一個是實現渲染側邊欄之前的一個token攔截,二是實現從後端獲取menuList以供拼接動態路由
router.beforeEach(async(to, from, next) => {
NProgress.start() // start progress bar
if (getToken()) { // determine if there has token
if (to.path === '/login') {
next({ path: '/' })
NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
} else {
if (!menuList) { //根據之前繫結的角色,通過cookie中的role向後端獲取menulist
const res = await fetchMenuList()
menuList = res.data
store.dispatch('GenerateRoutes', menuList) //利用vuex,在store中的premission.js中進行路由的拼接
}
next()
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) { // 在免登入白名單,直接進入
next()
} else {
next('/login') // 否則全部重定向到登入頁
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
})
3.在store中的premission.js中進行路由的拼接,思路是在後端根據role獲取到id,然後通過獲取到的id與寫在route.index裡的動態路由表進行比對拼接,如果包含獲取到的id的話就將路由表中的hidden設定為false,否則設為true來控制側邊欄是否顯示這個menu
const checkedId = [] //設定一個陣列,用來儲存許可權獲取到的route的id
function getCheckedId(menulist) { //將根據角色從後端獲取到的id進行foreach後儲存到checkedId中
menulist.forEach(item => {
checkedId.push(item.id)
if (item.childs.length) {
getCheckedId(item.childs)
}
})
}
function findIdRoute(asyncRouterMap, id) { //通過比對checkedId和寫在route中的路由表的id來進行hidden引數的true/false編寫
asyncRouterMap.forEach(item => {
if (id === item.id) {
item.hidden = false
}
if (item.children) {
findIdRoute(item.children, id)
}
})
}
function getRoutes(asyncRouterMap) { //呼叫findidroute函式
checkedId.forEach(id => {
findIdRoute(asyncRouterMap, +id)
})
}
const permission = { //vuex
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => { //將動態路由與靜態路由進行concat拼接,形成完整路由表
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
//路由拼接
actions: {
GenerateRoutes({ commit }, menulist) {
getCheckedId(menulist)
getRoutes(asyncRouterMap)
return new Promise(resolve => {
const accessedRouters = asyncRouterMap
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
ok至此,路由已經根據role拼接完畢,下面介紹下側邊欄如何去渲染出來,其原理就是遍歷之前算出來的permission_routers,然後通過vuex拿到之後動態v-for渲染而已
1:在sliderba的index中書寫如下
<sidebar-item v-for="route in permission_routers" :key="route.name" :item="route" :base-path="route.path"/>
<script>
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
export default {
components: { SidebarItem },
computed: {
...mapGetters([
'permission_routers',
'sidebar'
]),
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>
2.在sliderba的sidebaritem中書寫如下
hasOneShowingChild(children) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// temp set(will be used if only has one showing child )
this.onlyOneChild = item
return true
}
})
if (showingChildren.length === 1) {
return true
}
return false
},
resolvePath(...paths) {
return path.resolve(this.basePath, ...paths)
}
下面講一下前端登出:登出需要做兩件事,一是清除token,一是將vuex管理的使用者資訊state清空
1.在view層面設定點選函式
//登出
logout() {
this.$store.dispatch('FedLogOut').then(() => {
location.reload()// In order to re-instantiate the vue-router object to avoid bugs
})
}
2.在store的user.js中配置user相關的state和書寫登出actions
import { getToken, removeToken, removeUserInfo } from '@/utils/auth' //用於獲取token和userinfo
import { logout } from '../../service/common' //用於後端登出請求
const user = {
state: {
token: getToken(),
agent_id: '',
agent_name: '',
role_id: '', // 角色id
role_name: '',
user_name: '',
user_id: ''
},
mutations: {
SET_USERINFO: (state, user) => {
state = {
...state,
...user
}
console.log(state)
},
CLEAR_USERINFO: (state) => {
state.agent_id = ''
state.agent_name = ''
state.role_id = ''
state.role_name = ''
state.user_id = ''
state.user_name = ''
}
},
actions: {
saveUserinfo({ commit, state }, user) {
commit('SET_USERINFO', user)
},
// 後端登出
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout().then(() => {
commit('CLEAR_USERINFO')
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('CLEAR_USERINFO') //請求mutations
removeToken() //清除token
removeUserInfo() //清除cookes
resolve()
})
}
}
}
export default user
好了,這樣登陸,退出和許可權,以及動態路由已經實現,會繼續下更,如tree元件時間動態更改許可權,以及其他一些vue-element-admind自帶的元件的使用!
相關文章
- 分享一個基於 ABP(.NET 5.0) + vue-element-admin 管理後臺Vue
- react技術棧實踐(從前到後擼一個電影蒐集應用)React
- Linux程式後臺執行實踐Linux
- vue-element-admin改造接入後臺,搭建有來商城youlai-mall後臺前端管理平臺VueAI前端
- vue-element-admin後臺 登入時 [記住我] 功能Vue
- Workerman + laravel8 + vue-element-admin 擼了一個內網穿透應用LaravelVue內網穿透
- React開發管理後臺實踐1React
- 一小時完成後臺開發:DjangoRestFramework開發實踐DjangoRESTFramework
- 基於 vue-element-admin 高效開發後臺管理系統Vue
- 升級vue-element-admin,尋找前端中後臺更優解Vue前端
- Django Admin後臺管理:高效開發與實踐Django
- 攜程後臺低程式碼平臺的探究與實踐
- 手擼一個外賣點餐系統後臺,可以寫上簡歷的實戰專案!
- 後端開發的福音,vue+element實現的vue-element-admin前臺框架,開箱即用後端Vue框架
- vue-element-admin 入坑記(一)vue-element-admin 中文Vue
- Yii2 之 frontend 子模組實踐之一:新增前後臺子模組
- 後臺開發 -- 核心技術與應用實踐
- 後端多環境治理的實踐(一)後端
- 中後臺專案 - 查詢表格業務最佳實踐
- vue後臺管理系統許可權控制思考與實踐Vue
- 基於nuxt和iview搭建後臺管理系統實踐(1)UXView
- React開發管理後臺實踐3---新增新頁面React
- 後臺開發:核心技術與應用實踐 -- C++C++
- vue-element-admin實戰 | 第二篇: 最小改動接入後臺實現根據許可權動態載入選單Vue
- vue3+TS從0到1手擼後臺管理系統Vue
- 後臺開發-核心技術與應用實踐--TCP協議TCP協議
- vivo統一告警平臺設計與實踐
- 流批一體的實時特徵工程平臺建設實踐特徵工程
- React開發管理後臺實踐2---React基本內容學習React
- 一次前後端分離架構的實踐後端架構
- vue-element-admin與後端互動流程(補)(跨域)Vue後端跨域
- 擼擼Android的羊毛(一)----Activity啟動模式Android模式
- 手摸手,帶你用vue擼後臺 系列五(v4.0新版本)Vue
- 【PWA學習與實踐】(8)使用Service Worker進行後臺同步 – Background Sync
- 【PWA學習與實踐】(8)使用Service Worker進行後臺同步 - Background Sync
- 基於 Angular7,ng-zorro7.x 的中後臺實踐案例Angular
- 用 Laravel6.2 擼了一個微信通知推送平臺Laravel
- [平臺建設] HBase平臺建設實踐