Vue自定义指令最佳实践教程

Vue 3 显著增强了自定义指令的功能,使其封装更加灵活和易用。本文将分为基础和进阶两部分,介绍如何实现常用的自定义指令,并提供最佳的项目组织方式。

前言

  • 本文以复制文本的自定义指令详细介绍自定义指令的基础知识

  • 多个自定义指令如何进行代码及目录的组织

  • 如何更好的进行方法抽离使公共方法和自定义指令进行解耦

  • 自定义指令的高阶用法

1. 指令生命周期

Vue 3 自定义指令的生命周期如下:

  1. created:指令绑定到元素上时调用,且只调用一次。

  2. beforeMount:在元素插入 DOM 之前调用。

  3. mounted:元素插入 DOM 后调用。

  4. beforeUpdate:更新包含绑定值的元素时调用,发生在更新前。

  5. updated:更新包含绑定值的元素后调用。

  6. beforeUnmount:在绑定元素从 DOM 中移除前调用。

  7. unmounted:绑定元素从 DOM 中移除后调用。

通过这些生命周期,可以实现复杂的逻辑,例如初始化资源、监听事件或清理操作。

2. 基础部分:v-copy 指令

目标:实现一个简单的复制文本功能。

实现代码

将复制文本的逻辑单独抽离为工具函数:

// src/utils/copyToClipboard.js
export function copyToClipboard(text) {const input = document.createElement('textarea');input.value = text;document.body.appendChild(input);input.select();try {document.execCommand('copy');document.body.removeChild(input);return true;} catch (err) {document.body.removeChild(input);throw new Error('复制失败');}
}

封装 v-copy 指令:

// src/directives/copy.js
import { copyToClipboard } from '../utils/copyToClipboard';
import { isFunction } from '../utils/isType';
export default {mounted(el, binding) {const handleClick = () => {try {copyToClipboard(binding.value);console.log('复制成功!');} catch (err) {console.error('复制失败:', err);}};el.__handleClick__= handleClick;el.removeEventListener('click', el.__handleClick__);el.addEventListener('click', handleClick);},unmounted(el) {el.removeEventListener('click', el.__handleClick__);delete el.__handleClick__;},
};

使用方式

在 Vue 项目中全局注册指令:

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import copyDirective from './directives/copy';
const app = createApp(App);
app.directive('copy', copyDirective);
app.mount('#app');

在组件中使用:

<template><button v-copy="'这是复制的文本'">点击复制</button>
</template>

3. 进阶部分:完善的 v-copy 指令

目标:增强功能,支持成功和失败的事件回调。

实现代码

// src/directives/copy.js
import { copyToClipboard } from '../utils/copyToClipboard';
import { isFunction } from '../utils/isType';
export default {mounted(el, binding) {const handleClick = () => {const { success, error } = binding.arg || {};try {copyToClipboard(binding.value);if (isFunction(success)) {success();}} catch (err) {if (isFunction(error)) {error(err);}}};el.__handleClick__ = handleClick;el.removeEventListener('click', el.__handleClick__);el.addEventListener('click', handleClick);},unmounted(el) {el.removeEventListener('click', el.__handleClick__);delete el.__handleClick__;},
};

使用方式

<template><buttonv-copy:success="onCopySuccess"v-copy:error="onCopyError"v-copy="'高级复制文本'">高级复制按钮</button>
</template>
<script>
export default {methods: {onCopySuccess() {alert('复制成功!');},onCopyError(err) {alert('复制失败:' + err.message);},},
};
</script>

4. 指令参数说明

  1. binding.value:指令绑定的值,在这里是需要复制的文本。

  2. binding.arg:可选参数,例如用于传递回调函数(如 successerror)。

  3. binding.modifiers:修饰符对象,可用于定义指令的额外行为(如条件触发等)

5. 多指令项目的目录结构

当项目中包含多个自定义指令时,建议按照以下方式组织:

src/
├── directives/
│   ├── index.js         # 统一导出所有指令
│   ├── copy.js          # 复制指令
│   ├── focus.js         # 聚焦指令
│   └── lazy-load.js     # 图片懒加载指令
├── utils/
│   ├── copyToClipboard.js # 工具函数
│   └── isType.js         # 类型判断工具

统一导出指令

// src/directives/index.js
import copy from './copy';
import focus from './focus';
import lazyLoad from './lazy-load';
export default {copy,focus,lazyLoad,
};

全局注册指令

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import directives from './directives';
const app = createApp(App);
Object.keys(directives).forEach((key) => {app.directive(key, directives[key]);
});
app.mount('#app');

通过这样的目录结构,指令的维护和扩展将更加方便有序。如果需要新增指令,只需在 directives 目录中添加对应的文件并更新 index.js 即可。

希望本文能够帮助您更好地掌握 Vue 3 的自定义指令开发!

6.团队介绍

三翼鸟数字化技术平台-定制平台开发」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。

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

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

相关文章

用DrissionPage升级维基百科爬虫:更简洁高效的数据抓取方案

一、原方案痛点分析 原代码使用urllibBeautifulSoup组合存在以下问题&#xff1a; 动态内容缺失&#xff1a;无法获取JavaScript渲染后的页面内容 反爬能力弱&#xff1a;基础请求头易被识别为爬虫 代码冗余&#xff1a;需要单独处理SSL证书验证 扩展性差&#xff1a;难以应…

23种设计模式-结构型模式-代理

文章目录 简介问题解决方案代码核心设计要点 总结 简介 代理是一种结构型设计模式&#xff0c;让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问&#xff0c;并允许在把请求提交给对象前后进行一些处理。 问题 为什么要控制对于某个对象的访问呢&#xff1f…

基于Transformer框架实现微调后Qwen/DeepSeek模型的非流式批量推理

在基于LLamaFactory微调完具备思维链的DeepSeek模型之后(详见《深入探究LLamaFactory推理DeepSeek蒸馏模型时无法展示<think>思考过程的问题》),接下来就需要针对微调好的模型或者是原始模型(注意需要有一个本地的模型文件,全量微调就是saves下面的文件夹,如果是LoRA,…

基于OpenCV的指纹验证:从原理到实战的深度解析

指纹识别的技术革命与OpenCV的轻量级方案 在生物特征识别领域&#xff0c;指纹识别始终以独特性和稳定性占据核心地位。随着OpenCV等开源视觉库的普及&#xff0c;这项看似"高大上"的技术正逐步走向民用化开发。本文将突破传统算法框架&#xff0c;提出一套基于OpenC…

十五届蓝桥杯省赛Java B组(持续更新..)

目录 十五届蓝桥杯省赛Java B组第一题&#xff1a;报数第二题&#xff1a;类斐波那契数第三题&#xff1a;分布式队列第四题&#xff1a;食堂第五题&#xff1a;最优分组第六题&#xff1a;星际旅行第七题&#xff1a;LITS游戏第八题&#xff1a;拼十字 十五届蓝桥杯省赛Java B…

多模态学习(八):2022 TPAMI——U2Fusion: A Unified Unsupervised Image Fusion Network

论文链接&#xff1a;https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber9151265 目录 一.摘要 1.1 摘要翻译 1.2 摘要解析 二.Introduction 2.1 Introduciton翻译 2.2 Introduction 解析 三. related work 3.1 related work翻译 3.2 relate work解析 四…

电脑屏幕亮度随心控,在Windows上自由调整屏幕亮度的方法

调整电脑屏幕的亮度对于保护视力和适应不同环境光线条件非常重要。无论是在白天强光下还是夜晚昏暗环境中&#xff0c;合适的屏幕亮度都能让您的眼睛更加舒适。本文中简鹿办公小编将向您介绍几种在 Windows 系统中调整屏幕亮度的方法。 方法一&#xff1a;使用快捷键 大多数笔…

AF3 OpenFoldDataset类looped_samples方法解读

AlphaFold3 data_modules 模块的 OpenFoldDataset 类的 looped_samples 方法用于 循环采样数据,确保数据能被不断地提供,适用于 PyTorch 的 DataLoader 在训练过程中迭代读取数据。dataset_idx 指定了当前要处理的数据集(即 self.datasets[dataset_idx]) 源代码: def loo…

lua表table和JSON字符串互转

--print("local ssxc{\n"..string.gsub(str,":","").."\n}") Utils {} ---------------------------------------------------------------------------------- -- Lua-Table 与 string 转换 local function value2string(value, isA…

请谈谈分治算法,如何应用分治算法解决大规模问题?

分治算法实战解析与前端应用指南 分治算法本质剖析 分治算法的核心在于"分而治之"&#xff0c;其工作流程可分解为三个关键阶段&#xff1a; 分解阶段&#xff08;Divide&#xff09;&#xff1a;将复杂问题拆分为若干个相互独立的子问题攻克阶段&#xff08;Conqu…

基于BusyBox构建ISO镜像

1. 准备 CentOS 7.9 3.10.0-957.el7.x86_64VMware Workstation 建议&#xff1a;系统内核<3.10.0 使用busybox < 1.33.2版本 2. 安装busybox # 安装依赖 yum install syslinux xorriso kernel-devel kernel-headers glibc-static ncurses-devel -y# 下载 wget https://…

Node.js 与 MySQL:深入理解与高效实践

Node.js 与 MySQL:深入理解与高效实践 引言 随着互联网技术的飞速发展,Node.js 作为一种高性能的服务端JavaScript运行环境,因其轻量级、单线程和事件驱动等特点,受到了广大开发者的青睐。MySQL 作为一款开源的关系型数据库管理系统,以其稳定性和可靠性著称。本文将深入…

Android学习总结之handler源码级

一、核心类关系与线程绑定&#xff08;ThreadLocal 的核心作用&#xff09; 1. Looper 与 ThreadLocal 的绑定 每个线程的 Looper 实例通过 ThreadLocal<Looper> sThreadLocal 存储&#xff0c;确保线程隔离&#xff1a; public final class Looper {// 线程本地存储&…

群体智能优化算法-算术优化算法(Arithmetic Optimization Algorithm, AOA,含Matlab源代码)

摘要 算术优化算法&#xff08;Arithmetic Optimization Algorithm, AOA&#xff09;是一种新颖的群体智能优化算法&#xff0c;灵感来源于加、减、乘、除四种基本算术运算。在优化过程中&#xff0c;AOA 通过乘除操作实现全局探索&#xff0c;通过加减操作强化局部开发&#…

广告推荐算法:COSMO算法与A9算法的对比

COSMO算法与A9算法的概念解析 1. A9算法 定义与背景&#xff1a; A9算法是亚马逊早期为电商平台研发的核心搜索算法&#xff0c;主要用于优化商品搜索结果的排序和推荐&#xff0c;其核心逻辑围绕产品属性与关键词匹配展开。自2003年推出以来&#xff0c;A9通过分析商品标题…

EasyExcel 数据字典转换器实战:注解驱动设计

一、场景痛点与解决方案 1. 问题背景 在 Excel 导入导出场景中&#xff0c;开发者常面临以下问题&#xff1a; 数据可读性差&#xff1a;数据库存储的字典值&#xff08;如 1、true&#xff09;直接导出时难以理解双向转换复杂&#xff1a;导入时需将用户输入的标签反向解析…

五种音频器件综合对比——《器件手册--音频器件》

目录 音频器件 简述 1. 扬声器&#xff08;Speakers&#xff09; 2. 麦克风&#xff08;Microphones&#xff09; 3. 放大器&#xff08;Amplifiers&#xff09; 4. 音频接口&#xff08;Audio Interfaces&#xff09; 5. 音频处理器&#xff08;Audio Processors&#xff09…

红宝书第二十九讲:详解编辑器和IDE:VS Code与WebStorm

红宝书第二十九讲&#xff1a;详解编辑器和IDE&#xff1a;VS Code与WebStorm 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、核心区别&#xff1a;编辑器与IDE 代码编辑器&#xff08;如VS Code&#xff09…

虚拟电商-话费充值业务(五)充值成功逻辑和网络异常重试逻辑

一、网络异常重试逻辑编写 如果在对接供应商的过程中出现了网络异常&#xff0c;我们需要做一个补偿机制&#xff0c;在任务类型枚举类&#xff1a;TaskTypeEnum中有一种业务状态码是针对远程调用失败的 步骤一&#xff1a;在对接供应商的方法&#xff1a;SupplierServiceImp…

从零构建大语言模型全栈开发指南:第四部分:工程实践与部署-4.3.3低代码开发:快速构建行业应用(电商推荐与金融风控案例)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 从零构建大语言模型全栈开发指南-第四部分:工程实践与部署4.3.3 低代码开发:快速构建行业应用(电商推荐与金融风控案例)1. 低代码与AI结合的核心价值2. 电商推荐系统案例2.1 技术架构与实现2.2 性能…