搜索
您的当前位置:首页vuevuexvue-rouert权限路由(详细教程)

vuevuexvue-rouert权限路由(详细教程)

2023-11-29 来源:恩希娱乐
导读本小节我们介绍如何在 Vue 项目中使用 VueRouter。包括 VueRouter 的下载、什么是 VueRouter、如何使用 VueRouter 配置一个单页应用。其中,学习使用 VueRouter 配置一个单页应用是本节的重点。同学们在学完本节课程之后需要自己多尝试配置路由。 我们可以在官网 (VueRouter) 上直接下载 VueRouter 。 在 Vue 之后引入 VueRouter 会进行自动安装: 在一个模块化的打包系统中,您必须显式地通过 Vue.use () 来安装 V
这篇文章主要介绍了vue vuex vue-rouert后台项目——权限路由,通过本文可以很清除的捋清楚vue+vuex+vue-router的关系,本版本非常简单,适合初学者,需要的朋友可以参考下

项目地址: vue-simple-template

共三个角色:adan barbara carrie 密码全是:123456

adan 拥有 最高权限A 他可以看到 red , yellow 和 blue 页面(共三个页面)

barbara 拥有 权限B 他可以看到 red 和 yellow 页面

carrie 拥有 权限C 他可以看到 red 和 blue 页面

技术栈

webpack ---- 打包神器vue ---- JavaScript 框架vuex ---- 实现不同组件间的状态共享vue-router ---- 页面路由babel-polyfill ---- 将ES6代码转为ES5代码normalize.css ---- 重置掉该重置的样式element-ui ---- UI组件库

项目初始化

# cd 到项目文件夹cd weven-simple-template# 安装依赖 (本项目还安装了其他依赖详情 请见 package.json 文件)npm install# 运行项目npm run dev

项目结构

vue-cil 脚手架初始化项目后,我只修改过src文件夹

src├── App.vue ---- 页面入口├── api ---- api请求│ └── login.js ---- 模拟json对象数据├── assets ---- 主题 字体等静态资源│ └── logo.png├── components ---- 组件│ ├── index.vue│ └── login.vue ├── main.js ---- 初始化组件 加载路由├── router ---- 路由│ └── index.js└── store ---- vuex状态管理 ├── getters.js ├── index.js └── modules └── login.js

重点:

动态路由的关键在于router配置的 meta字段 和vuex的 状态共存 (不懂可以先查看官方文档)

router/index.js

// 初始化路由export default new Router({ routes: [ { path: '/login', name: 'Login', component: Login } ] });// 动态路由 meta 定义了roleexport const powerRouter =[ { path: '/',redirect:'/red', name: 'index',component: Index,hidden:false, children: [ { path: '/red', name: 'red', component: red,}, { path: '/yellow', name: 'yellow', component: yellow, meta: {role: 'B'}}, { path: '/blue', name: 'blue', component: blue, meta: {role: 'C'}} ] }];

store/modules/lo

Logins({ commit }, info){ return new Promise((resolve, reject) => { let data={}; loginByUserInfo.map(function (item) { //获取所以用户信息 if(info.username === item.username || info.pew === item.pew){ commit('SET_USERNAME',item.username); //将username和role进行存储 sessionStorage.setItem('USERNAME', item.username); //存入 session commit('SET_ROLE',item.role); sessionStorage.setItem('ROLE', item.role); return data={username:item.username,introduce:item.introduce}; }else{ return data; } }); resolve(data); }).catch(error => { reject(error); }); }, Roles({ commit }, newrouter){ return new Promise((resolve, reject) => { commit('SET_NEWROUER',newrouter); //存储最新路由 resolve(newrouter); }).catch(error => { reject(error); }); },

gin.js actions部分

Logins({ commit }, info){ return new Promise((resolve, reject) => { let data={}; loginByUserInfo.map(function (item) { //获取所以用户信息 if(info.username === item.username || info.pew === item.pew){ commit('SET_USERNAME',item.username); //将username和role进行存储 sessionStorage.setItem('USERNAME', item.username); //存入 session commit('SET_ROLE',item.role); sessionStorage.setItem('ROLE', item.role); return data={username:item.username,introduce:item.introduce}; }else{ return data; } }); resolve(data); }).catch(error => { reject(error); }); }, Roles({ commit }, newrouter){ return new Promise((resolve, reject) => { commit('SET_NEWROUER',newrouter); //存储最新路由 resolve(newrouter); }).catch(error => { reject(error); }); },

main.js

router.beforeEach((to, from, next) => { if(store.getters.role){ //判断role 是否存在 if(store.getters.newrouter.length !== 0){ next() //resolve 钩子 }else{ let newrouter if (store.getters.role == 'A') { //判断权限 newrouter = powerRouter } else { let newchildren = powerRouter[0].children.filter(route => { if(route.meta){ if(route.meta.role == store.getters.role){ return true } return false }else{ return true } }); newrouter = powerRouter newrouter[0].children = newchildren } router.addRoutes(newrouter) //添加动态路由 store.dispatch('Roles',newrouter).then(res => { next({ ...to }) }).catch(() => { }) } }else{ if (['/login'].indexOf(to.path) !== -1) { next() } else { next('/login') } }})

components/index.vue

// mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性...mapGetters([ 'newrouter' ])

此项目拿去 捋清楚 vue+vuex+vue-router 的关系是没问题的,这可以说的超级简单的版本,适合初学。上面的内容说的重点,其实也算是项目的全部啦

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在js中如何实现上传并压缩图片功能(详细教程)

使用JS如何计算两个时间相差数

在vue-cli webpack中如何引入jquery(详细教程)

在vue中有关文件使用方式

纯js如何生成下拉列表

小编还为您整理了以下内容,可能对您也有帮助:

21《Vue 入门教程》VueRouter 基础使用

本小节我们介绍如何在 Vue 项目中使用 VueRouter。包括 VueRouter 的下载、什么是 VueRouter、如何使用 VueRouter 配置一个单页应用。其中,学习使用 VueRouter 配置一个单页应用是本节的重点。同学们在学完本节课程之后需要自己多尝试配置路由。

我们可以在官网 (VueRouter) 上直接下载 VueRouter 。 在 Vue 之后引入 VueRouter 会进行自动安装:

在一个模块化的打包系统中,您必须显式地通过 Vue.use () 来安装 Vuex:

在本章节的 VueRouter 学习中,我们都将使用 CDN 的方式引入路由。

用 Vue.js + VueRouter 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 VueRouter 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 VueRouter 在哪里渲染它们。 在使用 VueRouter 之前,我们需要先了解 VueRouter 的两个内置组件:

接下来我们看一个基本例子:

实例演示

"运行案例" 可查看在线运行效果

代码解释: HTML 代码第 12-13 行,我们定义了两个跳转链接; HTML 代码第 15 行,我们使用 组件来渲染匹配组件; JS 代码第 5-7 行,我们定义了组件 Index; JS 代码第 9-11 行,我们定义了组件 Article; JS 代码第 13-16 行,我们定义了路由数组:

JS 代码第 18-20 行,创建 router 实例,然后传 routes 配置。 JS 代码第 24 行,通过 router 配置参数注入路由。

本节,我们带大家学习了 VueRouter。主要知识点有以下几点:

21《Vue 入门教程》VueRouter 基础使用

本小节我们介绍如何在 Vue 项目中使用 VueRouter。包括 VueRouter 的下载、什么是 VueRouter、如何使用 VueRouter 配置一个单页应用。其中,学习使用 VueRouter 配置一个单页应用是本节的重点。同学们在学完本节课程之后需要自己多尝试配置路由。

我们可以在官网 (VueRouter) 上直接下载 VueRouter 。 在 Vue 之后引入 VueRouter 会进行自动安装:

在一个模块化的打包系统中,您必须显式地通过 Vue.use () 来安装 Vuex:

在本章节的 VueRouter 学习中,我们都将使用 CDN 的方式引入路由。

用 Vue.js + VueRouter 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 VueRouter 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 VueRouter 在哪里渲染它们。 在使用 VueRouter 之前,我们需要先了解 VueRouter 的两个内置组件:

接下来我们看一个基本例子:

实例演示

"运行案例" 可查看在线运行效果

代码解释: HTML 代码第 12-13 行,我们定义了两个跳转链接; HTML 代码第 15 行,我们使用 组件来渲染匹配组件; JS 代码第 5-7 行,我们定义了组件 Index; JS 代码第 9-11 行,我们定义了组件 Article; JS 代码第 13-16 行,我们定义了路由数组:

JS 代码第 18-20 行,创建 router 实例,然后传 routes 配置。 JS 代码第 24 行,通过 router 配置参数注入路由。

本节,我们带大家学习了 VueRouter。主要知识点有以下几点:

如何优雅地在vue中添加权限控制示例详解

前言

在一个项目中,一些功能会涉及到重要的数据管理,为了确保数据的安全,我们会在项目中加入权限来每个用户的操作。作为前端,我们要做的是配合后端给到的权限数据,做页面上的各种各样的。

需求

因为这是一个工作上的业务需求,所以对于我来说主要有两个地方需要进行权限控制。

第一个是侧边菜单栏,需要控制显示与隐藏。

第二个就是页面内的各个按钮,弹窗等。

流程

1、如何获取用户权限?

后端(当前用户拥有的权限列表)-> 前端(通过后端的接口获取到,下文中我们把当前用户的权限列表叫做 permissionList)

2、前端如何做?

通过产品的需求,在项目中进行权限点的配置,然后通过 permissionList 寻找是否有配置的权限点,有就显示,没有就不显示。

3、然后呢?

没了。

当我刚开始接到这个需求的时候就是这么想的,这有什么难的,不就获取 permissionList 然后判断就可以了嘛。后来我才发现真正的需求远比我想象的复杂。

真正的问题

上面的需求有提到我们主要解决两个问题,侧边菜单栏的显示 & 页面内操作。

假设我们有这样一个路由的设置(以下只是一个例子):

import VueRouter from 'vue-router'

/* 注意:以下配置仅为部分配置,并且省去了 component 的配置 */

export const routes = [

{

path: '/',

name: 'Admin',

label: '首页'

},

{

path: '/user',

name: 'User',

label: '用户',

redirect: { name: 'UserList' },

children: [

{

path: 'list',

name: 'UserList',

label: '用户列表'

},

{

path: 'group',

name: 'UserGroup',

label: '用户组',

redirect: { name: 'UserGroupList' },

children: [

{

path: 'list',

name: 'UserGroupList',

label: '用户组列表'

},

{

path: 'config',

name: 'UserGroupConfig',

label: '用户组设置'

}

]

}

]

},

{

path: '/setting',

name: 'Setting',

label: '系统设置'

},

{

path: '/login',

name: 'Login',

label: '登录'

}

]

const router = new VueRouter({

routes

})

export default router

其中前两级路由会显示在侧边栏中,第就不会显示在侧边栏中了。

页面内操作的权限设置不需要考虑很多其他东西,我们主要针对侧边栏以及路由进行问题的分析,通过分析,主要有以下几个问题:

什么时候获取 permissionList,如何存储 permissionList

子路由全都没权限时不应该显示本身(例:当用户列表和用户组都没有权限时,用户也不应该显示在侧边栏)

默认重定向的路由没有权限时,应寻找 children 中有权限的一项重定向(例:用户路由重定向到用户列表路由,若用户列表没有权限,则应该重定向到用户组路由)

当用户直接输入没有权限的 url 时需要跳转到没有权限的页面或其他操作。(路由)

下面我们针对以上问题一个一个解决。

什么时候获取权限,存储在哪 & 路由

我这里是在 router 的 beforeEach 中获取的,获取的 permissionList 是存放在 vuex 中。

原因是考虑到要做路由的,以及方便后面项目中对权限列表的使用,以下是实现的示例:

首先我们加入权限配置到 router 上:

// 以下只展示部分配置

{

path: '/user',

name: 'User',

label: '用户',

meta: {

permissions: ['U_1']

},

redirect: { name: 'UserList' },

children: [

{

path: 'list',

name: 'UserList',

label: '用户列表',

meta: {

permissions: ['U_1_1']

}

},

{

path: 'group',

name: 'UserGroup',

label: '用户组',

meta: {

permissions: ['U_1_2']

},

redirect: { name: 'UserGroupList' },

children: [

{

path: 'list',

name: 'UserGroupList',

label: '用户组列表',

meta: {

permissions: ['U_1_2_1']

}

},

{

path: 'config',

name: 'UserGroupConfig',

label: '用户组设置',

meta: {

permissions: ['U_1_2_2']

}

}

]

}

]

}

可以看到我们把权限加在了 meta 上,是为了更简单的从 router.beforeEch 中进行权限判断,权限设置为一个数组,是因为一个页面可能涉及多个权限。

接下来我们设置 router.beforeEach :

// 引入项目的 vuex

import store from '@/store'

// 引入判断是否拥有权限的函数

import { includePermission } from '@/utils/permission'

router.beforeEach(async (to, from, next) => {

// 先判断是否为登录,登录了才能获取到权限,怎么判断登录就不写了

if (!isLogin) {

try {

// 这里获取 permissionList

await store.dispatch('getPermissionList')

// 这里判断当前页面是否有权限

const { permissions } = to.meta

if (permissions) {

const hasPermission = includePermission(permissions)

if (!hasPermission) next({ name: 'NoPermission' })

}

next()

}

} else {

next({ name: 'Login' })

}

})

我们可以看到我们需要一个判断权限的方法 & vuex 中的 getPermissionList 如下:

// @/store

export default {

state: {

permissionList: []

},

mutations: {

updatePermissionList: (state, payload) => {

state.permissionList = payload

}

},

actions: {

getPermissionList: async ({ state, commit }) => {

// 这里是为了防止重复获取

if (state.permissionList.length) return

// 发送请求方法省略

const list = await api.getPermissionList()

commit('updatePermissionList', list)

}

}

}

// @/utils/permission

import store from '@/store'

/**

* 判断是否拥有权限

* @param {Array<string>} permissions - 要判断的权限列表

*/

function includePermission (permissions = []) {

// 这里要判断的权限没有设置的话,就等于不需要权限,直接返回 true

if (!permissions.length) return true

const permissionList = store.state.permissionList

return !!permissions.find(permission => permissionList.includes(permission))

}

重定向问题

以上我们解决了路由的基本配置与权限如何获取,怎么路由跳转,接下来我们要处理的就是重定向问题了。

这一点可能和我们项目本身架构有关,我们项目的侧边栏下还有子级,是以下图中的 tab 切换展现的,正常情况当点击药品管理后页面会重定向到入库管理的 tab 切换页面,但当入库管理没有权限时,则应该直接重定向到出库管理界面。

所以想实现以上的效果,我需要重写 router 的 redirect,做到可以动态判断(因为在我配置路由时并不知道当前用户的权限列表)

然后我查看了 vue-router 的文档,发现了 redirect 可以是一个方法,这样就可以解决重定向问题了。

vue-router 中 redirect 说明 ,根据说明我们可以改写 redirect 如下:

// 我们需要引入判断权限方法

import { includePermission } from '@/utils/permission'

const children = [

{

path: 'list',

name: 'UserList',

label: '用户列表',

meta: {

permissions: ['U_1_1']

}

},

{

path: 'group',

name: 'UserGroup',

label: '用户组',

meta: {

permissions: ['U_1_2']

}

}

]

const routeDemo = {

path: '/user',

name: 'User',

label: '用户',

redirect: (to) => {

if (includePermission(children[0].meta.permissions)) return { name: children[0].name }

if (includePermission(children[1].meta.permissions)) return { name: children[1].name }

},

children

}

虽然问题解决了,但是发现这样写下去很麻烦,还要修改 router 的配置,所以我们使用一个方法生成:

// @/utils/permission

/**

* 创建重定向函数

* @param {Object} redirect - 重定向对象

* @param {string} redirect.name - 重定向的组件名称

* @param {Array<any>} children - 子列表

*/

function createRedirectFn (redirect = {}, children = []) {

// 避免缓存太大,只保留 children 的 name 和 permissions

const permissionChildren = children.map(({ name = '', meta: { permissions = [] } = {} }) => ({ name, permissions }))

return function (to) {

// 这里一定不能在 return 的函数外面筛选,因为权限是异步获取的

const hasPermissionChildren = permissionChildren.filter(item => includePermission(item.permissions))

// 默认填写的重定向的 name

const defaultName = redirect.name || ''

// 如果默认重定向没有权限,则从 children 中选择第一个有权限的路由做重定向

const firstPermissionName = (hasPermissionChildren[0] || { name: '' }).name

// 判断是否需要修改默认的重定向

const saveDefaultName = !!hasPermissionChildren.find(item => item.name === defaultName && defaultName)

if (saveDefaultName) return { name: defaultName }

else return firstPermissionName ? { name: firstPermissionName } : redirect

}

}

然后我们就可以改写为:

// 我们需要引入判断权限方法

import { includePermission, createRedirectFn } from '@/utils/permission'

const children = [

{

path: 'list',

name: 'UserList',

label: '用户列表',

meta: {

permissions: ['U_1_1']

}

},

{

path: 'group',

name: 'UserGroup',

label: '用户组',

meta: {

permissions: ['U_1_2']

}

}

]

const routeDemo = {

path: '/user',

name: 'User',

label: '用户',

redirect: createRedirectFn({ name: 'UserList' }, children),

children

}

这样稍微简洁一些,但我还是需要一个一个路由去修改,所以我又写了一个方法来递归 router 配置,并重写他们的 redirect:

// @/utils/permission

/**

* 创建有权限的路由配置(多级)

* @param {Object} config - 路由配置对象

* @param {Object} config.redirect - 必须是 children 中的一个,并且使用 name

*/

function createPermissionRouter ({ redirect, children = [], ...others }) {

const needRecursion = !!children.length

if (needRecursion) {

return {

...others,

redirect: createRedirectFn(redirect, children),

children: children.map(item => createPermissionRouter(item))

}

} else {

return {

...others,

redirect

}

}

}

这样我们只需要在最外层的 router 配置加上这样一层函数就可以了:

import { createPermissionRouter } from '@/utils/permission'

const routesConfig = [

{

path: '/user',

name: 'User',

label: '用户',

meta: {

permissions: ['U_1']

},

redirect: { name: 'UserList' },

children: [

{

path: 'list',

name: 'UserList',

label: '用户列表',

meta: {

permissions: ['U_1_1']

}

},

{

path: 'group',

name: 'UserGroup',

label: '用户组',

meta: {

permissions: ['U_1_2']

},

redirect: { name: 'UserGroupList' },

children: [

{

path: 'list',

name: 'UserGroupList',

label: '用户组列表',

meta: {

permissions: ['U_1_2_1']

}

},

{

path: 'config',

name: 'UserGroupConfig',

label: '用户组设置',

meta: {

permissions: ['U_1_2_2']

}

}

]

}

]

}

]

export const routes = routesConfig.map(item => createPermissionRouter(item))

const router = new VueRouter({

routes

})

export default router

当然这样写还有一个好处,其实你并不需要设置 redirect,这样会自动重定向到 children 的第一个有权限的路由

侧边栏显示问题

我们的项目使用的是根据路由的配置来生成侧边栏的,当然会加一些其他的参数来显示显示层级等问题,这里就不写具体代码了,如何解决侧边栏 children 全都无权限不显示的问题呢。

这里我的思路是,把路由的配置也一同更新到 vuex 中,然后侧边栏配置从 vuex 中的配置来读取。

由于这个地方涉及修改的东西有点多,而且涉及业务,我就不把代码拿出来了,你可以自行实验。

方便团队部署权限点的方法

以上我们解决了大部分权限的问题,那么还有很多涉及到业务逻辑的权限点的部署,所以为了团队中其他人可以优雅简单的部署权限点到各个页面中,我在项目中提供了以下几种方式来部署权限:

通过指令 v-permission 来直接在 template 上设置

<div v-permission="['U_1']"></div>

通过全局方法 this.$permission 判断,因为有些权限并非在模版中的

{

hasPermission () {

// 通过方法 $permission 判断是否拥有权限

return this.$permission(['U_1_1', 'U_1_2'])

}

}

这里要注意,为了 $permission 方法的返回值是可被监测的,判断时需要从 this.$sto

恩希娱乐还为您提供以下相关内容希望对您有帮助:

21《Vue 入门教程》VueRouter 基础使用

用 Vue.js + VueRouter 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 VueRouter 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 VueRout...

vue中如何实现后台管理系统的权限控制的方法步骤

1、创建路由表创建路由表实际上没有什么难度,照着vue-router官方文档给的示例直接写就行了。但是因为有部分页面是不需要访问权限的,所以需要将登录、404、维护等页面写到默认的路由中,而将其它的需要权限的页面写到一个变量或者一个文件...

vue项目 动态路由怎么做

上边第三步会给 global.antRouter赋值,这是一个全局变量(可以用vuex替代),菜单那边拿到路由,进行渲染

vue-router动态路由添加及路由刷新后消失的解决办法

1、取出非第一级的所有数据 2、映射出所有路由规则 3、添加路由 4、 登录成功后 保存菜单数据,保存后在vuex直接触发添加事件即可 this.commit('add_route')

vue实现页面权限中的菜单配置

index属性可以用菜单对象中的任意属性代替只需要它是唯一的 从后台获取不同角色的不同菜单数据,再通过两个递归函数来渲染菜单和动态添加菜单路由,实现页面的权限配置。https://erpang123.github.io/router-demo/dist-demo/...

vue路由通过url方式跳转到其他页面导致数据加载问题

1. 全局导航守卫 在router/index.js中设置前置守卫beforeEach,用于拦截路由跳转,需要在next()中调用next()或next(false)才能进行跳转。```router.beforeEach((to, from, next) =&gt; { // 在此处可以对路由进行权限控制等...

ts+vue3+vite+pinia+vue-router 踩坑合集

解决办法2 : 在声明路由数据时使用 RouteRecordRaw ; 下面是 RouteRecordRaw 的注解 pinia 使用: npm install pinia or yarn add pinia 定义单个store 使用useStore 动态路由权限踩坑 页面更新后提示报错信息: ...

VUE刷新丢失路由的解决方法

目前在使用VUE3.X开发,发现加载动态路由的话,由于刷新页面就会重新加载VUEX,故会丢失已存在的state,但是又不想localStorage,sessionStorage。经过多次试验,采取在权限验证里面的路由守卫里,添加 检测如果存在路由则跳转下一步...

路由解耦-解决Vue通过name和params进行跳转页面传参刷新参数丢失的问题...

最近在写Vue搭建的后台管理系统,在跳转页面时想要 保留 地址栏参数,使刷新参数还在,但是不想显示id:1,code:2的字段名id和code,怎么办呢? 通常我们在两个页面传数据时,一般会采用params,query,或者将数据用vuex,...

vue中如何优化单页应用首屏加载速度(详细)

建议按需引入iview中的组件使用nginx开启gzip减小网络传输的流量大小webpack开启gzip压缩若首屏为登录页,可以做成多入口,登录页单独分离为一个入口使用CDN资源,减小服务器带宽压力在index.html中引入cdn资源... &lt;body&gt; &lt;p id...

Top