指令
带v-的特殊属性即为指令,常见的指令有v-if,v-show,v-html,v-text,v-slot,v-bind,v-on,v-model等等,也可自定义指令。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。
除了name为必须外,其他的都可以没有,也可以有,修饰符可以有多个; v-focus v-aa.bb v-aa:aa.bb 都合法
name: 指令名称,v-开头的部分。v-bind: 简写: ;v-on:简写@
argument: 参数:开头的部分,为字符串类型,如果为:[xxx] 及为动态参数,xxx必须是字符串类型,且不能有空格等不合法字符。而且必须只能是小写(大写会被html转成小写,导致后面获取不到)
modifier:修饰符.开头的部分
value:值 =开头的部分,可以为任意类型,比如@click='clickEvent' clickEvent就是个函数类型,复杂数据可用对象
自定义指令:
<script setup> // 在模板中启用 v-focus const vFocus = { mounted: (el) => el.focus() } </script> <template> <input v-focus /> </template>
在 <script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令。在上面的例子中,vFocus 即可以在模板中以 v-focus 的形式使用。
1,全局自定义指令
const app = createApp({})
// 使 v-focus 在所有组件中都可用
app.directive('focus', {
/* ... */
})
2,指令钩子
指令钩子函数参数说明:除了el,其他的值都不能改变
el:绑定到的元素,可用来直接操作dom
binding:对象包含下面几个属性
{
value : 指令值;
oldValue: 改动前的值,仅用于updated,beforeupdate两个钩子中
arg:指令参数字符串v-my-directive:foo,值为foo
modifiers:修饰符对象,比如v-my-directive.foo.bar中,修饰符对象是 { foo: true, bar: true }
instance:使用该指令的组件实例
dir:指令的定义对象
}
vnode:绑定元素的底层VNode.
prevVnode:之前渲染中指令所绑定元素的VNode,仅用于updated,beforeupdate两个钩子中
const myDirective = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(el, binding, vnode) {
// 下面会介绍各个参数的细节
},
// 在元素被插入到 DOM 前调用
beforeMount(el, binding, vnode) {},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding, vnode) {},
// 绑定元素的父组件更新前调用
beforeUpdate(el, binding, vnode, prevVnode) {},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, binding, vnode, prevVnode) {},
// 绑定元素的父组件卸载前调用
beforeUnmount(el, binding, vnode) {},
// 绑定元素的父组件卸载后调用
unmounted(el, binding, vnode) {}
}
3,简化形式,自定义指令常在mounted和updated上实现相同的行为,不需要其他钩子,可做下简化
<div v-color="color"></div> app.directive('color', (el, binding) => { // 这会在 `mounted` 和 `updated` 时都调用 el.style.color = binding.value })
4,对子组件中使用,不建议
对子组件使用,会透传到子组件的根元素(如果子组件有多个根元素,将导致透传失败,并发出警告)