Vue自定义指令详解——以若依框架中封装指令为例分析

news2024/11/24 18:45:22

自定义指令

在Vue.js中,自定义指令提供了一种非常灵活的方式来扩展Vue的功能。以下是对Vue中自定义指令的详细解释:

一、自定义指令的基本概念

自定义指令允许开发者直接对DOM元素进行低层次操作,而无需编写大量的模板或者JavaScript代码。它们可以响应Vue的响应式系统,从而在数据变化时触发相应的DOM更新。

二、自定义指令的注册

  1. 全局注册

使用Vue.directive(name, definition)方法可以在全局范围内注册一个自定义指令。例如:

Vue.directive('my-directive', {
// 指令的定义
bind: function (el, binding, vnode, oldVnode) {
// 只调用一次,指令第一次绑定到元素时调用
// 在这里可以进行一次性的初始化设置
},
// 其他钩子函数...
});
  1. 局部注册

在组件中,可以使用directives选项来局部注册自定义指令。例如:

export default {
directives: {
'my-directive': {
// 指令的定义
bind: function (el, binding, vnode) {
// ...
},
// 其他钩子函数...
}
},
// 其他组件选项...
};

或者在setup函数中使用directives选项:

<script setup>
const myDirective = {
// 指令的定义
mounted: (el) => {
// ...
},
// 其他钩子函数...
};
</script>


<template>
<div v-my-directive></div>
</template>

三、自定义指令的钩子函数

自定义指令可以包含多个钩子函数,这些钩子函数在指令的不同生命周期阶段被调用:

  1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  2. inserted:被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
  3. update:所在组件的VNode更新时调用,但是可能发生在其子VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
  4. componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用。
  5. unbind:只调用一次,指令与元素解绑时调用。

四、自定义指令的参数和修饰符

  1. 参数:指令的参数可以是动态的,通过v-mydirective:[argument]="value"的形式传递。在指令的钩子函数中,可以通过binding.arg访问到参数的值。
  2. 修饰符:修饰符是以.开头的特殊后缀,用于对指令的行为进行微调。在指令的钩子函数中,可以通过binding.modifiers访问到修饰符的对象。

五、自定义指令的示例

以下是一个简单的自定义指令示例,用于在元素上添加点击时的动画效果:

Vue.directive('click-animate', {
bind(el, binding) {
// 定义点击时的动画效果
el.animateClick = () => {
el.classList.add('click');
setTimeout(() => {
el.classList.remove('click');
}, 100);
};
},
handleEvent(event) {
if (event.type === 'click') {
el.animateClick();
}
}
});

在模板中使用:


	<button v-click-animate>Click me!</button>

六、自定义指令的注意事项

  1. 在使用自定义指令时,请确保指令的名称不与Vue的内置指令冲突。
  2. 在指令的钩子函数中,请避免直接修改binding对象的属性,因为它是只读的。
  3. 如果需要在多个组件中重复使用自定义指令,建议将其注册为全局指令。

综上所述,Vue中的自定义指令提供了一种强大的方式来扩展Vue的功能,允许开发者直接对DOM元素进行低层次操作,并响应数据的变化。通过合理地使用自定义指令,可以实现各种复杂的DOM操作和逻辑控制。

若依框架中自定义指令分析

1.登录系统

根据用户后端返回用户信息,包括permisssions(Array)、roles和users 信息

 2.封装v-hasPermi指令(src/directive/permission/hasPermi.js)

用于判断当前用户是否有此权限。没有此权限(如:普通用户没有删除信息的权限)对应按钮就将移除【通过指令钩子函数的el参数修改DOM】

import store from '@/store'

export default {
   //可访问到DOM
  inserted(el, binding, vnode) {
    const { value } = binding
    const all_permission = "*:*:*";//所有权限
    const permissions = store.getters && store.getters.permissions//vuex中存的当前用户右的权限
    //绑定时为v-hasPermi="[]",值为数组类型

    if (value && value instanceof Array && value.length > 0) {
      const permissionFlag = value//当前按钮所需权限
       //当前用户是否存在此权限
      const hasPermissions = permissions.some(permission => {
        return all_permission === permission || permissionFlag.includes(permission)
      })

      if (!hasPermissions) {
        //没有对应权限就移除对应按钮!!!
        el.parentNode && el.parentNode.removeChild(el)
      }
    } else {
      throw new Error(`请设置操作权限标签值`)
    }
  }
}

3.导出所有自定义指令至插件index.js(src/directive/index.js) 

将项目封装的所有指令以插件的型式导出去

import hasRole from './permission/hasRole'
import hasPermi from './permission/hasPermi'
import dialogDrag from './dialog/drag'
import dialogDragWidth from './dialog/dragWidth'
import dialogDragHeight from './dialog/dragHeight'
import clipboard from './module/clipboard'

const install = function(Vue) {
  Vue.directive('hasRole', hasRole)
  Vue.directive('hasPermi', hasPermi)
  Vue.directive('clipboard', clipboard)
  Vue.directive('dialogDrag', dialogDrag)
  Vue.directive('dialogDragWidth', dialogDragWidth)
  Vue.directive('dialogDragHeight', dialogDragHeight)
}

if (window.Vue) {
  window['hasRole'] = hasRole
  window['hasPermi'] = hasPermi
  Vue.use(install); // eslint-disable-line
}

export default install

4.使用指令

使用 v-directiveName="value"

        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['system:dept:add']"
        >新增</el-button>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

云渲染:服务器机房与物理机房两者有什么区别

云渲染选择服务器机房与物理机房两者主要区别在哪里呢&#xff1f; 服务器机房和物理机房作为云渲染的基础设施&#xff0c;各自扮演着不同的角色。 服务器机房的特点 服务器机房&#xff0c;通常指的是那些专门用于托管服务器的设施&#xff0c;它们可能位于云端&#xff0c…

即插即用篇 | YOLOv8 引入 代理注意力 AgentAttention

Transformer模型中的注意力模块是其核心组成部分。虽然全局注意力机制具有很强的表达能力,但其高昂的计算成本限制了在各种场景中的应用。本文提出了一种新的注意力范式,称为“代理注意力”(Agent Attention),以在计算效率和表示能力之间取得平衡。代理注意力使用四元组(Q…

机器学习基础02

目录 1.特征工程 1.1特征工程概念 1.2特征工程的步骤 1.3特征工程-特征提取 1.3.1字典特征提取 1.3.2文本特征提取 英文文本提取 中文文本提取 1.3.3TF-IDF文本特征词的稀有程度特征提取 2.无量纲化 2.1归一化 2.2标准化 2.3fit、fit_transform、transform 3.特征…

vue-h5:在h5中实现相机拍照加上身份证人相框和国徽框

1.基础功能 参考&#xff1a; https://blog.csdn.net/weixin_45148022/article/details/135696629 https://juejin.cn/post/7327353533618978842?searchId20241101133433B2BB37A081FD6A02DA60 https://www.freesion.com/article/67641324321/ https://github.com/AlexKrat…

【Elasticsearch入门到落地】1、初识Elasticsearch

一、什么是Elasticsearch Elasticsearch&#xff08;简称ES&#xff09;是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。它使用Java编写&#xff0c;基于Apache Lucene来构建索引和提供搜索功能&#xff0c;是一个分布式、可扩展、近实…

Rust开发一个命令行工具(一,简单版持续更新)

依赖的包 cargo add clap --features derive clap命令行参数解析 项目目录 代码 main.rs mod utils;use clap::Parser; use utils::{editor::open_in_vscode,fs_tools::{file_exists, get_file, is_dir, list_dir, read_file}, }; /// 在文件中搜索模式并显示包含它的行。…

Xshell,Shell的相关介绍与Linux中的权限问题

目录 XShell的介绍 Shell的运行原理 Linux当中的权限问题 Linux权限的概念 Linux权限管理 文件访问者的分类&#xff08;人&#xff09; 文件类型和访问权限&#xff08;事物属性&#xff09; 文件权限值的表示方法 文件访问权限的相关设置方法 如何改变文件的访问权…

golang 实现比特币内核:公钥的 SEC 编码格式详解

比特币作为区块链的一个应用,它建立在分布式系统之上,‘节点’遍布全球。为了使所有节点协同工作并作为一个整体系统运行,需要保持所有节点同步在相同的状态中,也就是说节点之间需要频繁通信,并且相互交换大量数据消息。这要求在网络上传输的消息或数据要使用某种格式编码…

【JAVA】使用IDEA创建maven聚合项目

【JAVA】使用IDEA创建maven聚合项目 1.效果图 2.创建父模块项目 2.1删除父模块下面的src目录以及不需要的maven依赖 3创建子模块项目 3.1右击父模块项目选择Module… 3.2创建子模块 3.3删除子模块下不需要的maven依赖 4.子模块创建完成后引入SpringBoot依赖启动项目

《Django 5 By Example》阅读笔记:p17-p53

《Django 5 By Example》学习第2天&#xff0c;p17-p53总结&#xff0c;总计37页。 一、技术总结 1.数据库迁移 python manage.py makemigrations blog python manage.py sqlmigrate blog 0001 python manage.py migrate 2.ORM Django自带ORM。 3.view (1)定义 p42, …

基于物联网的智能超市快速结算系统

摘 要 当今社会的商品层出不穷&#xff0c;人们因为越来越多大型仓储超市的出现使得生活更加便利&#xff0c;但许多随之而来的新问题也给人们带来了许多的不便&#xff0c;例如商家一直被更换标签不及时、货物丢失、超市内物品更换处理不及时、超市内人流高峰期人流控制不得…

阿里云Linux安装Docker服务报错问题

今天使用了阿里云99计划的服务器&#xff0c;之前用惯了 CentOS&#xff0c;这次想体验下阿里云调教的 Alibaba Cloud Linux 3 系统性能&#xff0c;但是在安装 docker 的时候遇到了问题&#xff01; 传统安装方式 之前习惯安装docker方式&#xff1a; #查看是否已经安装的D…

数据结构《链表》

文章目录 前言一、什么是链表&#xff1f;二、单向链表2.1 单向链表的个人实现2.2 单向链表的例题 三、双向链表3.1 双向链表的个人实现3.2 关于真正的java中提供的链表的使用 总结 前言 提示&#xff1a;概念来源于&#xff1a;>>LinkedList<< 一、什么是链表&am…

typesScript 制作一个简易的区块链(2)

pow 机制 1.哈希函数的特点 说到 pow 机制&#xff0c;就离不开哈希函数&#xff0c;哈希函数具有以下特点&#xff1a; 输入长度不固定&#xff0c;输出长度固定输入不同&#xff0c;输出不同输入相同&#xff0c;输出相同不可逆雪崩效应 雪崩效应&#xff1a;输入变量中只…

[Codesys]常用功能块应用分享-BMOV功能块功能介绍及其使用实例说明

官方说明 功能说明 参数 类型 功能 pbyDataSrcPOINTER TO BYTE指向源数组指针uiSizeUINT要移动数据的BYTE数pbyDataDesPOINTER TO BYTE指向目标数组指针 实例应用-ST IF SYSTEM_CLOCK.AlwaysTrue THENCASE iAutoState OF0: //读写完成信号在下次读写信号的上升沿或复位信号…

【树莓派raspberrypi烧录Ubuntu远程桌面登入树莓派】

提示&#xff1a;本文利用的是Ubuntu主机和树莓派4B开发板&#xff0c;示例仅供参考 文章目录 一、树莓派系统安装下载前准备工作下载安装树莓派的官方烧录软件imagerimager的使用方法 二、主机与树莓SSH连接查看数梅派IP地址建立ssh连接更新树莓派源地址 三、主机端远程桌面配…

Linux权限和开发工具(3)

文章目录 1. 简单理解版本控制器Git1. 如何理解版本控制 2. Git的操作2.1 Git安装2.2 Git提交身份2.3 Git提交命令2.4 Git版本管理2.5 Git下的同步 3. gdb命令3.1解决gdb的难用问题3.2 gdb/cgdb的使用 1. 简单理解版本控制器Git 1. 如何理解版本控制 我们在做项目的时候可能会…

如何在 Django 中生成 Excel 文件并上传至 FastDFS

文章目录 如何在 Django 中生成 Excel 文件并上传至 FastDFS需求背景主要任务 实现步骤 创建 Excel 文件上传 Excel 文件到 FastDFSclient.conf 保存文件 URL 到数据库组合完整的流程总结 如何在 Django 中生成 Excel 文件并上传至 FastDFS 在很多实际应用场景中&#xff0c;我…

电子应用产品设计方案-3:插座式自动温控器设计

一、设计 插座式自动温控器作为一种便捷的温度控制设备&#xff0c;在日常生活和工业应用中发挥着重要作用。它能够根据环境温度的变化自动控制连接设备的电源通断&#xff0c;实现对温度的精确调节和节能控制。本设计旨在提供一种功能强大、易于使用、安全可靠的插座式自动温控…

Redis的常用命令大全

目录 一、Redis简介 1.键值型 2.NoSQL 2.1关联和非关联 2.2查询方式 2.3事务 2.4总结 二、Redis常见命令 2.1 通用命令 2.2 String 命令 2.3 Hash类型 2.4 List类 2.5 Set集合 2.6 SortedSet类型 一、Redis简介 Redis是一种键值型的NoSql数据库&#xff0c;这里…