-
• vue3 自定义指令
-
• Vue3 自定义指令的基本结构
-
• Vue3 自定义指令简单的示例:
-
• vue3 组件中自定义指令
-
• vue3 组件 setup 语法糖 中 自定义指令
-
• 扩展:vue2 中如何自定义指令
-
• 全局指令
-
• 局部指令
vue3 自定义指令
Vue3 中自定义指令允许开发者扩展 Vue 的 HTML 属性功能,创建自定义的行为。
Vue3 对自定义指令的 API 进行了更新,与 Vue2 相比更加灵活和可组合。
Vue3 自定义指令的基本结构
在 Vue3 中定义自定义指令的基本结构如下:
// 全局注册一个自定义指令
const myDirective = {
// 指令被绑定到元素时调用,仅调用一次
created: (el, binding, vnode) => {},
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
mounted: (el, binding, vnode) => {},
// 指令所在组件的 VNode 及其子 VNode 更新时调用
updated: (el, binding, vnode) => {},
// 指令所在组件的 VNode 及其子 VNode 销毁时调用
beforeUnmount: (el, binding, vnode) => {},
// 指令所在组件的 VNode 及其子 VNode 完全卸载时调用
unmounted: (el, binding, vnode) => {},
// 钩子函数可以接收三个参数:
// el:指令所绑定的元素
// binding:一个对象,包含以下属性:
// - name:指令名
// - value:传递给指令的值(例如:v-my-directive="value" 中的 value)
// - oldValue:上一个值,在 updated 和 beforeUpdate 钩子中可用
// - arg:传给指令的参数(例如:v-my-directive:foo 中的 "foo")
// - modifiers:一个对象,包含了修饰符列表(如 .prevent、.stop 等)
// vnode:Vue 编译生成的虚拟节点
// oldVnode:上一个虚拟节点,在 updated 和 beforeUpdate 钩子中可用
}
// 全局注册
app.directive('my-directive', myDirective)
// 或者在单个组件内局部注册
export default {
directives: {
'my-directive': {
// 在此处定义指令逻辑
mounted(el, binding, vnode) {
// 示例逻辑:当元素挂载时,获取焦点
el.focus()
},
},
},
}
在模板中使用自定义指令的语法是 v-my-directive
,如果需要传递参数,则可以写作 v-my-directive:arg
,同时也可以添加修饰符,例如 v-my-directive.modifier1.modifier2
。
Vue3 中自定义指令的设计理念鼓励通过组合API(如 ref
、computed
和 watch
)来实现更复杂的功能,而非过度依赖指令机制。
不过对于一些特定场景下,自定义指令仍然是一种简洁且强大的工具。
Vue3 自定义指令简单的示例:
在Vue3中自定义指令的步骤如下,并给出一个简单的示例:
假设我们要创建一个自定义指令,该指令用于当元素挂载到页面时自动聚焦到输入框。
首先,定义一个自定义指令对象,其中包含必要的生命周期钩子函数:
// 自定义指令逻辑
const focusDirective = {
mounted(el, binding) {
// el 是指令绑定到的 DOM 元素
// binding 是一个对象,包含了如 value、arg、modifiers 等信息
if (binding.value && typeof binding.value === 'string') {
// 如果传入了参数,则根据参数决定是否聚焦(此处简单地判断参数为 "auto" 时聚焦)
if (binding.value === 'auto') {
el.focus();
}
} else {
// 若无参数或参数不为 "auto",默认进行聚焦
el.focus();
}
},
};
// 全局注册自定义指令
const app = createApp(App);
app.directive('focus', focusDirective);
// 或者在某个组件内部局部注册
export default {
directives: {
focus: focusDirective,
},
};
然后,在模板中使用这个自定义指令:
<input type="text" v-focus />
<!-- 或带有参数 -->
<input type="text" v-focus:auto />
在这个例子中,v-focus
指令会在相应输入框挂载到DOM后立即获取焦点。
如果指定了参数 :auto
并且其值等于 'auto'
,则会执行聚焦操作;否则,无论是否有参数,都会默认聚焦。当然,实际应用中可以根据需求定制更复杂的逻辑。
vue3 组件中自定义指令
在Vue3组件中自定义指令,可以局部注册到该组件内部。
以下是一个在单个组件内创建和使用自定义指令的示例:
// 假设这是你的某个Vue组件
import { createApp, ref } from 'vue';
// 定义一个局部指令逻辑
const focusDirective = {
mounted(el) {
el.focus();
},
};
export default {
// 指令注册到组件的 directives 对象上
directives: {
focus: focusDirective,
},
setup() {
const inputText = ref('');
return {
inputText,
};
},
template: `
<div>
<!-- 在本组件模板内使用自定义指令 -->
<input type="text" v-focus :value="inputText" @input="event => (inputText.value = event.target.value)" />
</div>
`,
};
// 创建应用并挂载根组件
const app = createApp(App);
app.mount('#app');
在这个例子中,我们创建了一个名为 focus
的局部指令,它会在元素被挂载后立即调用 el.focus()
方法来聚焦对应的DOM元素。然后我们在组件内部的 <input>
标签上通过 v-focus
使用这个自定义指令,这样当输入框渲染时会自动获取焦点。
在实际项目中,你可能还需要根据需求处理更多复杂的指令逻辑,比如传递参数、响应式更新等。
vue3 组件 setup 语法糖 中 自定义指令
在Vue3的<script setup>
语法糖中,自定义指令仍然不会直接在setup
函数内部定义,而是按照Vue3的传统方式在组件外部或者全局进行注册。
这是因为自定义指令是一个全局或局部注册的机制,并非组件实例的功能。
然而,在使用<script setup>
编写组件时,你可以结合Composition API来创建指令逻辑,并在同一个文件内局部注册这个指令,然后在模板中应用它。
以下是如何在一个单文件组件(SFC)内局部注册一个自定义指令:
<template>
<input type="text" v-focus />
</template>
<script setup lang="ts">
import { onMounted, ref, directive } from 'vue';
// 定义指令逻辑
const focusDirective = {
mounted(el) {
// 使用onMounted钩子确保DOM已挂载
onMounted(() => {
el.focus();
});
},
};
// 局部注册指令到当前组件作用域
defineComponent({
directives: {
focus: focusDirective,
},
});
</script>
这里需要注意的是,在<script setup>
语法糖中并没有直接提供对directives
选项的暴露和设置。
因此,需要借助defineComponent
函数来注册指令,但这并不是标准做法,因为<script setup>
的目的之一是减少此类手动操作。
实际项目中,自定义指令通常会独立出来并在全局或者模块级别进行注册,而不是在每个使用它的组件内都重新注册一次。
例如:
// directives/focus.js
export const focus = {
mounted(el) {
el.focus();
},
};
// 在main.js或者其他合适的地方全局注册
import { createApp } from 'vue';
import { focus } from './directives/focus';
const app = createApp(App);
app.directive('focus', focus);
app.mount('#app');
然后在任何组件中,包括使用<script setup>
的组件,都可以直接使用v-focus
指令而无需额外配置。
扩展:vue2 中如何自定义指令
在Vue2中自定义指令可以分为全局指令和局部指令两种方式。
全局指令
全局指令可以在整个Vue应用范围内生效,你可以在任何组件中使用它。创建全局指令的步骤如下:
// 在你的Vue应用初始化文件或单独的插件文件中
Vue.directive('my-directive', {
// 钩子函数
bind: function (el, binding, vnode) { // 绑定元素时调用
// 'el' 是绑定指令的DOM元素
// 'binding' 是一个对象,包含:
// - name: 指令名(不带v-前缀)
// - value: 指令的绑定值
// - oldValue: 上一个绑定值(仅在update钩子中可用)
// - expression: 指令表达式的字符串形式
// - arg: 传递给指令的参数(如果有)
// - modifiers: 修饰符对象
// 'vnode' 是虚拟节点
// 示例:为元素添加一个class
el.classList.add(binding.value);
},
inserted: function (el, binding, vnode) { // 插入DOM时调用 }
update: function (el, binding, vnode) { // 当绑定值变化时调用 }
componentUpdated: function (el, binding, vnode) { // 元素更新后及它的子元素也完成更新后调用 }
unbind: function (el, binding, vnode) { // 指令与元素解绑时调用 }
});
局部指令
局部指令是在单个组件内部定义并使用的,通过组件的 directives
选项来实现:
Vue.component('MyComponent', {
directives: {
'my-directive': {
bind: function (el, binding, vnode) {...},
// 其他钩子函数...
}
},
template: `
<div v-my-directive="someValue">...</div>
`,
...
});
在上述代码中,my-directive
就是我们自定义的指令名称,它会在相应钩子函数执行时对DOM元素进行操作。根据需要,你可以选择在适当的钩子函数内编写逻辑,比如响应数据变化、操作DOM属性或样式等。
原文始发于微信公众号(前端爱好者):vue3.x学习笔记之自定义指令
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/267270.html