前言
今天用一个简易案例来进行以下vue知识点的学习,案例包括以下知识
- 路由守卫
- 路由鉴权
- pinia
- 自定义指令
还包含css4新特性变量的使用 和elementPlus(vue3)组件库的使用,本篇文章偏向详细的思路讲解和知识的连贯,想要全部代码的,文章底部我会给出链接,好了,话不多我们快速分享。
pinia的使用
pinia是中央数据管理仓库,所以一般管理一些全局,公共,需要隔代传递或者是一些兄弟组件之间进行传递的状态(数据)。如果对pinia一点都不了解的,可以看看我这篇文章不了解pinia?5分钟带你快速了解 - 掘金 (juejin.cn)
看下面这个效果,上面的是一个header一个组件,侧边栏是sidebar组件,在这种情况下我们需要进行点击之后切换sidebar组件的状态,这里就涉及到了兄弟组件之间的进行状态传递。 所以我们将状态放入在pinia里面
pinia非常建议数据状态模块化,也就是一个组件的数据状态专门使用一个store文件进行存储,这里我们创建使用sidebar.js文件进行存储。
javascript
// 导入defineStore 进行 Store的创建
import { defineStore } from 'pinia';
// 一个文件就是一个状态模块
export const useSidebarStore = defineStore('sidebar', {
// 数据也就是状态存放的地方,需要用的数据需要return出去
state: () => {
return {
collapse: false
}
},
// 状态改变的方法
actions: {
// collapse状态的切换
handleCollapse() {
this.collapse = !this.collapse
}
}
})
本个案例还用到了另一个store状态存储,这个是关于路由鉴权的,放在下面一起讲解
路由守卫+路由鉴权
先来讲讲什么是路由鉴权,路由鉴权顾名思义就是进行路由操作(页面跳转)跳转一些页面的时候需要进行权限校验。比如qq普通用户只能看非vip的内容,黄钻会员可以查看浏览信息等都是鉴权的体现
如何跳转页面时进行权限校验工作这就要引出我们的路由守卫了。
路由守卫其实就是一个api ,vue在跳转网页的时候进行了一些钩子函数(官方提供的特殊时刻触发的事件)帮助我们在路由加载的时候进行一些权限校验和一些别的操作。这就是路由守卫和路由鉴权。
本文用的是全局路由守卫也就是所有页面跳转都会触发 ,那具体使用用本文案例进行实现。
请听题:
本文中,我们有两个角色,一个admin,一个user ,在登录后已知角色的情况下 如何在vue提供的钩子函数中也就是路由守卫中进行权限校验 呢?并且保证每个页面的权限都保证正确。提前说一下这是一提开放题,我们拥有的已知的工具和数据有:
1-pinia(中央数据仓库可供所有组件访问),2-路由守卫(每次路由跳转都会触发),3-路由的配置(路由的参数和需要的权限)4-用户的具体权限数据(对象如admin:['1','2'])
我的思路:
这里先声明,实现的方式有很多种。不需要纠结于是否符合你的答案,当然如果你有别的思路或者是更好的解法欢迎在评论区讨论。本人主打就是虚心接受- ̗̀(๑ᵔ⌔ᵔ๑),这里只是不希望大家的兴趣被答案不一致给减弱了。
首先我根据登录之后触发路由守卫首先判断中央数据仓库是否存有现有的用户相关的信息比如用户是admin或者是user,没有的话就首先进行中央数据仓库的设置,
利用用户具体权限数据进行用户匹配在中央仓库设置好用户当前具有的权限之后,继续进行下面的路由守卫逻辑
获取当前要去往的路由信息,在路由中配置好的属性中(一般放在meta)取出当前路由的权限在中央仓库已经存储好的用户权限信息进行匹配,没有则跳转403页面,有则正常进入指定页面。可以看看效果 全部代码的话这里就不贴了太长了,贴一下进行路由守卫部分,
vbnet
router.beforeEach((to, from, next) => {
Nprogress.start();
document.title = to.meta.title
const role = localStorage.getItem("ms_name");
const permissStore = usePermissStore();
// console.log(role, permiss[role], permiss[role].includes(to.meta.permiss))
if (!role && to.meta.noAuth !== true) {
next('/login')
}
else if (typeof to.meta.permiss == 'string' && !permissStore.key.includes(to.meta.permiss)) {
next('/403')
}
else {
next();//不需要登录或者登录了,有相应的权限,允许访问
}
})
自定义指令
在案例的实现中,我们会遇到不同权限的用户展示的页面是不一样的。权限高的用户页面显示的内容比权限低的用户展示的内容更多。所以在进入页面的时候,我们需要对一些需要权限校验的页面元素进行判断是否进行展示。实现的方法有不少,比如v-if指令也可以判断,但今天我要讲的是自定义指令。
相信v-if,v-show等官方自定义指令大家都知道,vue官方允许开发者扩展框架的功能,通过创建自己的指令来处理一些标准指令。
在 Vue.js 中,自定义指令可以通过 Vue.directive()
方法来注册。 自定义指令可以有以下几种钩子方法:
- bind : 这个钩子被调用时,指令第一次绑定到元素上,可以在这里初始化一些东西。参数包括
el
(DOM 元素),binding
(指令绑定的值),以及vnode
(虚拟节点)。 - inserted: 当被绑定的元素被插入到 DOM 中时调用此钩子。
- mounted :是自定义指令的一个钩子函数,它在被绑定的元素被插入到DOM中时调用。这意味着,当指令绑定的元素首次出现在DOM中时,
mounted
函数将被执行。 - update: 当指令所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令值会更新为新值。
- componentUpdated: 指令所在组件的 VNode 及其子 VNode 完全更新后调用此钩子。
- unbind: 不管绑定元素的 VNode 卸载,还是指令被显式解除绑定,这个钩子都会被调用。
这里我们可以自定义一个指令,在mounted钩子中间进行判断是否存在用户权限中,如果不存在就将元素hidden起来。这样子我们就实现了想要的功能。
代码:
javascript
app.directive('permiss', {
// el dom , binding 绑定的属性
mounted(el, binding) {
if (binding.value && !permissStore.key.includes(String(binding.value))) {
el['hidden'] = true;
}
}
})
css4 变量
CSS变量允许你在CSS中定义可重用的值,这可以是颜色、长度、频率、百分比、数字、字符串或任何有效的CSS值。CSS变量使用var()
函数引用,定义时使用--
前缀。
CSS变量的定义
CSS变量在:root
伪类或其他任何选择器下定义。:root
伪类代表文档的根元素(html),通常用于定义全局变量。
css
root {
--primary-color: #ff0000; /* 红色 */
--secondary-color: #00ff00; /* 绿色 */
--padding-size: 10px;
}
引用CSS变量
在CSS中,你可以使用var()
函数引用定义好的变量。
css
body {
background-color: var(--primary-color);
padding: var(--padding-size);
}
回退值
var()
函数可以接受一个可选的第二个参数作为回退值,当变量未定义时使用。
css
body {
background-color: var(--primary-color, #000); /* 如果变量未定义,则使用黑色 */
}
变量的作用域
CSS变量可以在任何选择器中定义,但它们的范围取决于定义它们的选择器。例如,如果在.my-class
中定义了一个变量,那么它只在具有.my-class
类的元素中可用。
css
my-class {
--local-color: #0000ff; /* 蓝色 */
color: var(--local-color);
}
继承
CSS变量遵循CSS的继承规则,如果在父元素中定义了一个变量,那么子元素可以使用它,除非子元素中重新定义了同名的变量。这也是为什么简易写在:root也就是html元素上,这样页面所用元素都可以使用该变量。
计算
CSS变量可以与其他CSS值一起计算。
css
:root {
--base-font-size: 16px;
--large-font-size: calc(var(--base-font-size) * 2);
}
body {
font-size: var(--base-font-size);
}
h1 {
font-size: var(--large-font-size);
}
结语
本篇文章主要分享的是实现过程中的思路和一些知识的讲解,想要完整代码的可以点击下方的网盘链接。链接: pan.baidu.com/s/12_jSGpBL...
本次分享就到这里啦,喜欢的小伙伴话可以点个关注或者是赞,谢谢- ̗̀(๑ᵔ⌔ᵔ๑)。