vue3自定义指令(图文教程)

序:

简单,但是没怎么用,但是小伙伴问了,所以做个教程。

自定义指令我只关心3件事

  1. 干啥用的,怎么用的,解决什么痛点
  2. 怎么全局
  3. 博文有查阅及参考过以下文章,
  1.  vue3:自定义指令_vue3自定义指令-CSDN博客 
  2. vue3目录结构详细说明及文件命名规范_vue3目录结构解析-CSDN博客
  3. 自定义指令 | Vue.js

正文

一、干啥用的,怎么用的,解决什么痛点

     简单,举个例子,ul>li结构,我想每个li都显示自己在这个li里面排第几位(index)索引

<template>
	<ul>
		<li>1</li>
		<li>2</li>
		<li>2</li>
	</ul>
</template>

你正常是不是下面这么,这么玩,没毛病吧

<template>
	<ul>
		<li v-for="(v,i) in arr" :key="i" :index="i">1</li>
	</ul>
</template>
<script setup lang="ts" >
	var arr:string[]=[1,2,3]
</script>
<style lang="scss" scoped>
</style>

问题来了,我要每偶数行背景改变,你要么class加个on去判断颜色,要么style去%2,没错吧。来看自定义指令

<template>
	<ul>
		<li v-for="(v,i) in arr" :key="i" :i="i" v-cyc>1</li>
	</ul>
</template>
 
<script setup lang="ts" >
	var arr:number[]=[1,2,3]
	const vCyc={
		mounted: (el:any) => {
			var index=el.getAttribute("i");
			if(index%2==1){
				el.style.backgroundColor = "yellow"
			}
		}
	}
</script>
<style lang="scss" scoped>
	
</style>

有小伙伴就会问了,什么年代,还在dom节点操作,难道我不会把逻辑封装个组件里面吗?这个自定义组件解决什么痛点?有必要吗

是!你完全可以封装在一个组件里。

问题是你能保证一直都是ul和li结构的组件吗,就像说,table列表也要偶数行改北京你是不是还要去改一次table在封装一次?那隔天select的偶数行也要呢?

<template>
	<select>
		<option v-for="(v,i) in arr" :key="i" :i="i" v-cyc>{{v}}</option>
	</select>
</template>
 
<script setup lang="ts" >
	var arr:number[]=[1,2,3]
	const vCyc={
		mounted: (el:any) => {
			var index=el.getAttribute("i");
			if(index%2==1){
				el.style.backgroundColor = "yellow"
			}
		}
	}
</script>
<style lang="scss" scoped>
	
</style>

看明白吗?v-cyc 加上后,自动就去加背景了,不会有哪个公司那么闲,每个个性化的业务都来封装一个组件吧,那得是多大的公司,时间不要钱的吗,肯定是效率第一呀

二、怎么全局

来,先看目录结构,从网上扒下来

my-vue3-project/
├── public/           # 静态资源文件夹,其中的文件会直接复制到构建输出目录中,无需经过编译处理
│   ├── favicon.ico    # 网站图标
│   └── index.html    # 应用程序入口HTML文件,Vue应用将挂载于此文件中的特定元素上

├── src/
│   ├── assets/        # 静态资源目录,包含图片、字体等未经过webpack编译的文件,可使用import导入并在构建时进行处理
│   ├── components/    # 组件目录,按照功能或类别划分存放单文件组件(.vue文件)
│   │   ├── Common/     # 公共组件目录
│   │   ├── Layout/     # 布局组件目录
│   │   └── ...         # 其他分类组件目录
│   ├── directives/    # 自定义指令目录,存放Vue自定义指令实现
│   ├── hooks/         # Vue Composition API 的自定义 Hooks 目录,用于组织和复用可组合的逻辑单元
│   ├── layouts/       # 应用布局相关的组件存放处,例如通用页面布局组件
│   │   ├── AppLayout.vue 
│   │   └── ...         # 其他布局相关页面组件
│   ├── pages/          # 页面组件目录,根据功能模块划分不同页面组件
│   │   ├── Home/       # 主页或首页相关页面组件
│   │   │   ├── Index.vue
│   │   │   └── ...
│   │   ├── User/       # 用户管理相关的页面组件
│   │   │   ├── Profile.vue
│   │   │   ├── Settings.vue
│   │   │   └── ...
│   │   ├── Product/    # 产品管理相关的页面组件
│   │   │   ├── List.vue
│   │   │   ├── Detail.vue
│   │   │   └── ...
│   │   └── ...         # 其他功能模块的页面组件目录
│   ├── plugins/       # Vue 插件配置目录,存放全局注册的插件及其配置
│   ├── router/        # 路由配置目录,主要包含index.js路由文件,用于配置应用程序的路由规则
│   ├── store/         # Vuex 状态管理目录,用于集中管理组件状态和数据流
│   ├── styles/        # 样式文件目录,包括全局样式、主题样式等
│   ├── utils/         # 工具函数和类库目录,存放项目中常用的工具函数、辅助类等
│   ├── App.vue        # 应用程序根组件,整个应用的入口点,通常包含路由视图和其他全局共享组件
│   ├── main.ts        # 应用程序入口脚本,用于初始化Vue实例、引入并配置路由、状态管理等核心模块
│   └── shims-vue.d.ts # TypeScript 类型声明文件,为Vue相关API提供类型支持

├── tests/             # 测试相关文件目录,存放单元测试、集成测试等代码
├── .env.*             # 环境变量配置文件,根据不同环境如开发、生产等设置不同的环境变量
├── .eslintrc.js       # Eslint 配置文件,用于定义项目的代码风格规范和错误检查规则
├── .gitignore         # Git 忽略文件,列出不需要添加到版本控制的文件或目录
├── package-lock.json       #  npm 包管理器中用于锁定项目依赖版本的文件
├── package.json       # npm 包配置文件,包括项目依赖、脚本命令、项目信息等元数据
├── vite.config.ts     # Vite 构建工具的配置文件,用于定制Vite的构建行为(如果使用Vite构建系统)
├── README.md          # 项目文档和说明文件,介绍项目结构、启动方式及注意事项等
├── tsconfig.json          # TypeScript 项目的核心配置文件,用于指定编译选项、包含的源文件、排除的文件等信息
├── tsconfig.node.json          # 针对 Node.js 应用程序进行更细粒度的 TypeScript 编译设置
├── .prettierrc        # Prettier 代码格式化配置文件,定义代码格式化规则
├── .ls-lint.yml       # Linting 规则配置文件,例如针对Less预处理器的代码风格检查规则
└── changelog.md       # 更新日志文件,记录项目的版本迭代和更新内容

好,来看明白每,在src下新建个directives文件夹,在新建个index.ts、和cyc.ts

index.ts

import registerFocus from './cyc'; // 获取焦点
export default function registerDirectives(app: any) {
    registerFocus(app);
}

cyc.ts

export default function(app: any) {
app.directive("cyc", {
    mounted(el: any) {
		let index=el.getAttribute("i");
		if(index%2==1){
			el.style.backgroundColor = "yellow"
		}
    }
  })
}

然后呢?

main.ts,加这两个东西,位置如下图,app是createApp(App),你不一样的话记得改

import registerDirectives from './directives'
registerDirectives(app)

你记得把你原来test.vue这个测试页面的代码删了,就留下这样

<template>
	<ul>
		<li v-for="(v,i) in arr" :key="i" :i="i" v-cyc>1</li>
	</ul>
</template>
 
<script setup lang="ts" >
	var arr:number[]=[1,2,3]
</script>
<style lang="scss" scoped>
	
</style>

好了,差不多可以了 

来,我在上个指令的周期

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {}
}

我也是写给自己看的,你要是卡到,去公众号:”程序员员野区"。留言,我看到回你,也可以直接公众号回复加群,来加雪狼的粉丝群

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue 3中的自定义指令封装是一种扩展Vue的能力,允许开发者在DOM元素上添加自定义行为。下面是Vue 3中自定义指令封装的步骤: 1. 创建自定义指令:使用`app.directive`方法来创建自定义指令。该方法接受两个参数,第一个参数是指令名称,第二个参数是一个对象,包含了指令的各种钩子函数和配置选项。 2. 钩子函数:自定义指令可以通过钩子函数来定义其行为。常用的钩子函数有: - `beforeMount`:在指令绑定的元素挂载到DOM之前调用。 - `mounted`:在指令绑定的元素挂载到DOM之后调用。 - `beforeUpdate`:在指令所在组件更新之前调用。 - `updated`:在指令所在组件更新之后调用。 - `beforeUnmount`:在指令所在组件卸载之前调用。 - `unmounted`:在指令所在组件卸载之后调用。 3. 配置选项:除了钩子函数外,还可以通过配置选项来定义自定义指令的行为。常用的配置选项有: - `bind`:在指令绑定到元素时立即调用,只调用一次。 - `update`:在指令所在组件的VNode更新时调用,可能会调用多次。 - `unbind`:在指令从元素上解绑时调用,只调用一次。 下面是一个示例,演示了如何在Vue 3中封装一个自定义指令: ```javascript // 创建Vue实例 const app = Vue.createApp({}); // 创建自定义指令 app.directive('my-directive', { beforeMount(el, binding, vnode) { // 指令绑定到元素之前的操作 }, mounted(el, binding, vnode) { // 指令绑定到元素之后的操作 }, beforeUpdate(el, binding, vnode) { // 指令所在组件更新之前的操作 }, updated(el, binding, vnode) { // 指令所在组件更新之后的操作 }, beforeUnmount(el, binding, vnode) { // 指令所在组件卸载之前的操作 }, unmounted(el, binding, vnode) { // 指令所在组件卸载之后的操作 } }); // 将Vue实例挂载到DOM元素上 app.mount('#app'); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪狼之夜

打个赏,让博主知道博文没白写

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值