当前位置: 首页 > 科技观察

教你如何在Vue3中自定义命令_0

时间:2023-03-18 17:49:39 科技观察

TienChin项目的前端是Vue3,前端有这样一个需求:前端页面的一些按钮要根据用户的权限显示。如果用户有相应的权限,则显示相应的按钮;如果用户没有相应的权限,则该按钮被隐藏。大致就是这样的需求。看到这个需求,可能有些朋友首先想到的是使用v-if命令。这个命令确实可以用。但是,由于用户一般都有多个权限,甚至可能存在通配符,所以这个比较并不是一件容易的事,必须写方法。..因此,如果能用一个命令来实现这个功能,就显得专业多了。动手吧,让我们看看如何在Vue3中自定义指令。1.结果展示先来看看自定义命令的最终用法:删除用户朋友们看到了,这个v-hasPermission是我们的自定义命令。如果当前用户有user:delete权限,就会显示这个按钮。如果当前用户没有此权限,则不会显示此按钮。2.指令的基本知识首先,让我们和我的朋友们谈谈。Vue2和Vue3在自定义说明上有一些差异,并不完全一致。下面的介绍主要针对Vue3的介绍。先给小伙伴们分享一下我们是怎么做的,然后在讲解代码的时候再解释一下各个参数的含义。2.1两种作用域自定义指令可以定义为全局或局部。在正式上线之前,需要了解自定义命令有两个作用域,一个是本地自定义命令,一个是全局自定义命令。局部自定义指令只能在当前.vue文件中使用,全局指令可以在所有.vue文件中使用。2.1.1本地指令可以直接在当前.vue文件中定义,如下:directives:{focus:{//指令的定义mounted(el){el.focus()}}}但是在Vue3中,也可以这样写:这里我自定义了一个叫onceClick的命令。将这个命令添加到一个按钮button上之后,可以设置按钮button被点击多长时间才会失效,防止用户重复点击,朋友们看到这个命令的执行逻辑其实很简单。el相当于添加这个命令的元素,监听元素的点击事件。如果点击元素时元素没有被禁用,则设置元素为禁用,给出一个过期的crontask,使元素可用。下面是具体的参数,下面宋哥给大家详细介绍一下。但这只是一个局部指令,只能在当前.vue文件中使用。我们还可以定义一个全局指令,以便它可以在所有.vue文件中使用。2.1.2全局指令我们一般将全局指令写在main.js中,或者单独写一个js文件导入到main.js中。下面的例子直接写在main.js中:constapp=createApp(App);app.directive('onceClick',{mounted(el,binding,vnode){el.addEventListener('click',()=>{if(!el.disabled){el.disabled=true;setTimeout(()=>{el.disabled=false;},binding.value||1000);}});}})这样,我们就可以随时随地使用命令v-onceClick。可能小伙伴们一头雾水,自定义命令的时候mounted和这里的参数有什么问题,接下来宋兄就来详细介绍一下这些方法和参数。2.2七个钩子函数在Vue3中,主要有七个用于自定义指令的钩子函数(这一个与Vue2有很大不同):created:在应用绑定元素的属性或事件监听器之前调用。当在调用普通的v-on事件监听器之前需要在事件监听器中附加指令时,这很有用。beforeMount:当指令首次绑定到元素时且在挂载父组件之前调用。mounted:绑定元素的父组件挂载后调用,大部分自定义指令都写在这里。beforeUpdate:在更新包含该组件的VNode之前调用。updated:在包含组件的VNode及其子组件的VNode更新后调用。beforeUnmount:在绑定元素的父组件被卸载之前调用unmounted:只调用一次,当指令与元素解除绑定并且父组件被卸载时。钩子函数虽然很多,看起来有点唬人,但是挂载函数其实是我们日常开发中使用最多的。2.3四个参数这里有七个钩子函数。钩子函数中有回调参数,回调参数有四个。意思和Vue2基本一样:el:指令绑定的元素,可以用来直接操作DOM,我们松哥说如果要实现一个指令,可以自动判断一个组件是显示还是显示hidden,那么就可以通过el对象来操作DOM节点,进而实现组件的隐藏。binding:我们通过自定义命令传递的各种参数主要存在于这个对象中,这个对象有很多属性。以下属性是我们在日常开发中使用较多的属性:name:命令名称,不包括v-前缀。value:命令的绑定值,例如:在v-hasPermission="['user:delete']"中,绑定值为'user:delete',但请注意,这个绑定值可以是一个数组或普通对象。关键是看你具体绑定了什么。在2.1节的例子中,我们的值是一个数字。expression:字符串形式的指令表达式。例如,在v-my-directive="1+1"中,表达式为"1+1"。arg:传递给命令的参数,可选。例如v-hasPermission:[name]="'zhangsan'",参数为"name"。vnode:Vue编译生成的虚拟节点。oldVnode:前一个虚拟节点,仅在update和componentUpdatedhooks中可用。除了el,其他参数应该是只读的,不应该被修改。如果需要在hook之间共享数据,建议通过元素的数据集来完成。2.4动态参数还有一种动态参数,这里分享给小伙伴们。一般情况下,我们在自定义指令时传递的参数都是通过binding.value获取的,但是还有一种方法是通过binding.arg获取参数。让我给你一个简单的例子。假设我们有上面的onceClick指令。默认时间单位是毫秒。如果我们现在想设置时间单位,我们可以这样写:constapp=createApp(App);app.directive('onceClick',{mounted(el,binding,vnode){el.addEventListener('click',()=>{if(!el.disabled){el.disabled=true;lettime=binding.value;if(binding.arg=="s"){time=time*1000;}setTimeout(()=>{el.disabled=false;},time);}});}})自定义命令时获取绑定。arg的值,这样就可以知道时间单位了。使用该命令时,方法如下:ClickMetimeUnit是预先定义的变量。3.自定义权限说明好了,有了上面的基础知识,我们来看看我们文章的主题,自定义权限说明。让我写一个简单的例子:constusersPermissions=['user'];app.directive('hasPermission',{mounted(el,binding,vnode){const{value}=binding;letf=usersPermissions.some(p=>{returnp.indexOf(value)!==-1;});if(!f){el.parentNode&&el.parentNode.removeChild(el);}}})usersPermissions表示当前用户的权限,正常情况下应该从服务器加载数据,这里为简单起见,直接定义。具体逻辑很简单。先从binding中提取出value的值,也就是当前控件需要的权限,然后用一个some函数遍历usersPermissions,检查usersPermissions中是否有满足条件的值。如果没有,说明当前用户没有显示该组件所需的权限,那么就需要隐藏该组件。隐藏的方式是获取当前组件的父组件,然后从父组件中移除当前组件。这是一个全局命令。定义好后,我们可以直接在组件中使用:删除用户