使用elementuiadmin去掉默認mock權(quán)限控制的設(shè)置
elementuiadmin去掉默認mock權(quán)限控制的設(shè)置
一般前后端分離的項目,前端都很少通過mock模擬數(shù)據(jù)來調(diào)用測試,因為后期api出來后,可能還得修改結(jié)構(gòu),頗為麻煩。
本文從實踐中總結(jié),完全去掉默認的mock控制。
1.找到vue.config.js文件,去掉mock的加載
devServer: { ? ? port: port, ? ? open: true, ? ? overlay: { ? ? ? ? warnings: false, ? ? ? ? errors: true ? ? } ? ? // before: require('./mock/mock-server.js') // 注釋掉這一行 }
2.找到main.js,注釋掉相關(guān)mock
// if (process.env.NODE_ENV === 'production') { // ?const { mockXHR } = require('../mock') // ?mockXHR() // }
3.login.vue登錄頁面,直接調(diào)用api/user.js下的方法。
先引用login和reg進來,否則用默認的登錄接口會再調(diào)用用戶詳情接口
import { login, reg } from '@/api/user'
把原來的登錄方法注釋掉,直接調(diào)用成功后,把登錄token值set到j(luò)s-cookie里
handleLogin() { ? ? ? this.$refs.loginForm.validate(valid => { ? ? ? ? if (valid) { ? ? ? ? ? this.loading = true ? ? ? ? ? login(this.loginForm).then((res) => { ? ? ? ? ? ? if (res && res.code === 0 && res.data && res.data.token) { ? ? ? ? ? ? ? setToken(res.data.token) ? ? ? ? ? ? ? this.$router.push({ path: this.redirect || '/', query: this.otherQuery }) ? ? ? ? ? ? ? this.loading = false ? ? ? ? ? ? } ? ? ? ? ? }).catch(() => { ? ? ? ? ? ? this.loading = false ? ? ? ? ? }) ? ? ? ? ? // this.$store.dispatch('user/login', this.loginForm) ? ? ? ? ? // ? .then(() => { ? ? ? ? ? // ? ? this.$router.push({ path: this.redirect || '/', query: this.otherQuery }) ? ? ? ? ? // ? ? this.loading = false ? ? ? ? ? // ? }) ? ? ? ? ? // ? .catch(() => { ? ? ? ? ? // ? ? this.loading = false ? ? ? ? ? // ? }) ? ? ? ? } else { ? ? ? ? ? console.log('error submit!!') ? ? ? ? ? return false ? ? ? ? } ? ? ? }) ? ? },
4.登錄后就是菜單的展示問題了,找到/layout/components/Sidebar/index.vue文件,去掉權(quán)限控制permission_routes參數(shù),改為:
<sidebar-item v-for="route in getRouterList" :key="route.path" :item="route" :base-path="route.path" /> ? import routesArr from '@/router/index' export default { ? components: { SidebarItem, Logo, routesArr }, ? computed: { ? ? getRouterList() { ? ? ? return routesArr.options.routes ? ? }, ? ? ...mapGetters([ ? ? ? // 'permission_routes', // 注釋掉 ? ? ? 'sidebar' ? ? ]),
OK!完美!
vue-elementui-admin的動態(tài)權(quán)限控制
最近打算仔細的學習一下vue-elemnetui-admin的代碼,一是工作需要用到,需要加工一些東西,還有一個就是打算之后好好學習vue,看看源碼啥的,所以先從這個框架學起來。
都是一些自己的學習筆記,做一些記錄,有不對的地方懇請大家指出,可以一起討論。
學習了一下permission文件夾下的role.js,用來控制不同用戶能夠查看菜單的權(quán)限
<template> <div class="app-container"> <el-button type="primary" @click="handleAddRole">New Role</el-button> <el-table :data="rolesList" style="width: 100%;margin-top:30px;" border> <el-table-column align="center" label="Role Key" width="220"> <template slot-scope="scope"> {{ scope.row.key }} </template> </el-table-column> <el-table-column align="center" label="Role Name" width="220"> <template slot-scope="scope"> {{ scope.row.name }} </template> </el-table-column> <el-table-column align="header-center" label="Description"> <template slot-scope="scope"> {{ scope.row.description }} </template> </el-table-column> <el-table-column align="center" label="Operations"> <template slot-scope="scope"> <el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button> <el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button> </template> </el-table-column> </el-table> <el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Role':'New Role'"> <el-form :model="role" label-width="80px" label-position="left"> <el-form-item label="Name"> <el-input v-model="role.name" placeholder="Role Name" /> </el-form-item> <el-form-item label="Desc"> <el-input v-model="role.description" :autosize="{ minRows: 2, maxRows: 4}" type="textarea" placeholder="Role Description" /> </el-form-item> <el-form-item label="Menus"> <el-tree ref="tree" :check-strictly="checkStrictly" :data="routesData" :props="defaultProps" show-checkbox node-key="path" class="permission-tree" /> </el-form-item> </el-form> <div style="text-align:right;"> <el-button type="danger" @click="dialogVisible=false">Cancel</el-button> <el-button type="primary" @click="confirmRole">Confirm</el-button> </div> </el-dialog> </div> </template> <script> import path from 'path' import { deepClone } from '@/utils' import { getRoutes, getRoles, addRole, deleteRole, updateRole } from '@/api/role' const defaultRole = { key: '', name: '', description: '', routes: [] } export default { data() { return { role: Object.assign({}, defaultRole), routes: [], // 路由列表 rolesList: [], // 角色列表以及對應(yīng)的路由信息 dialogVisible: false, dialogType: 'new', checkStrictly: false, defaultProps: { children: 'children', label: 'title' } } }, computed: { routesData() { return this.routes } }, created() { // Mock: get all routes and roles list from server this.getRoutes() // 獲取全部的路由列表 this.getRoles() // 獲取全部角色加里面的權(quán)限路由 }, methods: { async getRoutes() { const res = await getRoutes() // res是全部路由列表,由constantRoutes靜態(tài)路由和asyncRoutes動態(tài)路由拼接組成 this.serviceRoutes = res.data // 將全部路由列表賦值給serviceRoutes this.routes = this.generateRoutes(res.data) // 生成樹的數(shù)據(jù) }, async getRoles() { const res = await getRoles() // 獲取全部的角色信息,以及角色對應(yīng)的路由信息 this.rolesList = res.data // 拿到表格數(shù)據(jù) }, // Reshape the routes structure so that it looks the same as the sidebar // 產(chǎn)生最終路由的方法,參數(shù)是全部路由信息和‘/' generateRoutes(routes, basePath = '/') { const res = [] for (let route of routes) { // 遍歷所有路由信息 // skip some route if (route.hidden) { continue } // hidden屬性為true,則繼續(xù) const onlyOneShowingChild = this.onlyOneShowingChild(route.children, route) // 得到子路由的完整信息 // console.log('onlyOneShowingChild', onlyOneShowingChild) // 有二級菜單的路由返回的false,進行遞歸 // 你可以設(shè)置 alwaysShow: true,這樣它就會忽略之前定義的規(guī)則,一直顯示根路由 // 如果有chilren和生成的信息且不是跟路由 if (route.children && onlyOneShowingChild && !route.alwaysShow) { route = onlyOneShowingChild } const data = { path: path.resolve(basePath, route.path), title: route.meta && route.meta.title } // recursive child routes if (route.children) { // 遞歸路由的子路由 data.children = this.generateRoutes(route.children, data.path) } res.push(data) // 放進res中生成路由 } return res }, // 把樹的數(shù)據(jù)routes放進數(shù)組里 generateArr(routes) { let data = [] routes.forEach(route => { data.push(route) if (route.children) { const temp = this.generateArr(route.children) if (temp.length > 0) { data = [...data, ...temp] } } }) return data }, handleAddRole() { this.role = Object.assign({}, defaultRole) if (this.$refs.tree) { this.$refs.tree.setCheckedNodes([]) } this.dialogType = 'new' this.dialogVisible = true }, // 顯示該角色的菜單信息 handleEdit(scope) { this.dialogType = 'edit' // 修改角色權(quán)限菜單 this.dialogVisible = true this.checkStrictly = true this.role = deepClone(scope.row) // 深度克隆該行的信息,包括路由信息 console.log('role',this.role) this.$nextTick(() => { const routes = this.generateRoutes(this.role.routes) // 產(chǎn)生該角色所能查看到的路由信息 // 設(shè)置點開該角色能看到的菜單已被選中,this.generateArr(routes)接收勾選節(jié)點數(shù)據(jù)的數(shù)組, this.$refs.tree.setCheckedNodes(this.generateArr(routes)) // set checked state of a node not affects its father and child nodes this.checkStrictly = false // 在顯示復選框的情況下,是否嚴格的遵循父子不互相關(guān)聯(lián)的做法 }) }, handleDelete({ $index, row }) { this.$confirm('Confirm to remove the role?', 'Warning', { confirmButtonText: 'Confirm', cancelButtonText: 'Cancel', type: 'warning' }) .then(async() => { await deleteRole(row.key) this.rolesList.splice($index, 1) this.$message({ type: 'success', message: 'Delete succed!' }) }) .catch(err => { console.error(err) }) }, // 生成勾選完的路由結(jié)構(gòu) generateTree(routes, basePath = '/', checkedKeys) { const res = [] for (const route of routes) { // 生成每個路由的絕對路徑 const routePath = path.resolve(basePath, route.path) // recursive child routes if (route.children) { // 遞歸children route.children = this.generateTree(route.children, routePath, checkedKeys) } // 如果勾選結(jié)果的路徑包含有遍歷全部路由的當前路由,或該路由沒有子路由,把該路由放置 if (checkedKeys.includes(routePath) || (route.children && route.children.length >= 1)) { res.push(route) } } return res }, async confirmRole() { const isEdit = this.dialogType === 'edit' const checkedKeys = this.$refs.tree.getCheckedKeys() // 選中的所有節(jié)點的keys生成數(shù)組 console.log('checkedKeys', checkedKeys) // 深度克隆全部路由列表,將勾選完的路由和全部路由對比,生成勾選完的完整路由結(jié)構(gòu) this.role.routes = this.generateTree(deepClone(this.serviceRoutes), '/', checkedKeys) // 如果是修改角色權(quán)限菜單 if (isEdit) { await updateRole(this.role.key, this.role) // 調(diào)接口更新該角色菜單權(quán)限 for (let index = 0; index < this.rolesList.length; index++) { if (this.rolesList[index].key === this.role.key) { this.rolesList.splice(index, 1, Object.assign({}, this.role)) break } } } else { // 如果不是編輯狀態(tài),就是新增角色信息,調(diào)接口新增角色 const { data } = await addRole(this.role) this.role.key = data.key this.rolesList.push(this.role) } const { description, key, name } = this.role this.dialogVisible = false this.$notify({ // 提示信息 title: 'Success', dangerouslyUseHTMLString: true, message: ` <div>Role Key: ${key}</div> <div>Role Name: ${name}</div> <div>Description: ${description}</div> `, type: 'success' }) }, // reference: src/view/layout/components/Sidebar/SidebarItem.vue onlyOneShowingChild(children = [], parent) { // 參數(shù)是子路由。父路由 let onlyOneChild = null const showingChildren = children.filter(item => !item.hidden) // 拿到子路由中children中不是hidden的路由展示 // 當只有一條子路由時,該子路由就是自己 // When there is only one child route, the child route is displayed by default if (showingChildren.length === 1) { // path.resolve()方法可以將多個路徑解析為一個規(guī)范化的絕對路徑,parent.path為根路徑,onlyOneChild.path為拼接路徑 onlyOneChild = showingChildren[0] onlyOneChild.path = path.resolve(parent.path, onlyOneChild.path) // 返回子路由的完整路由信息 return onlyOneChild } // 如果沒有要顯示的子路由,則顯示父路由 // Show parent if there are no child route to display if (showingChildren.length === 0) { onlyOneChild = { ... parent, path: '', noShowingChildren: true } return onlyOneChild } return false } } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue上傳項目到git時,如何忽略node_modules文件夾
這篇文章主要介紹了vue上傳項目到git時,如何忽略node_modules文件夾,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09解決vue2使用腳手架配置prettier報錯prettier/prettier:context.getPhysical
這篇文章主要介紹了解決vue2使用腳手架配置prettier報錯prettier/prettier:context.getPhysicalFilename is not a function問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03vue-router 按需加載 component: () => import() 報錯的解決
這篇文章主要介紹了vue-router 按需加載 component: () => import() 報錯的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09vue自定義插件封裝,實現(xiàn)簡易的elementUi的Message和MessageBox的示例
這篇文章主要介紹了vue自定義插件封裝,實現(xiàn)簡易的elementUi的Message和MessageBox的示例,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-11-11在vue項目中 實現(xiàn)定義全局變量 全局函數(shù)操作
這篇文章主要介紹了在vue項目中 實現(xiàn)定義全局變量 全局函數(shù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10