在 Vue 中,指令是直接编辑 DOM 的最佳方式之一。
一些示例包括 、 、 等。如果你在 Vue 工作过,你就会熟悉指令:v-if,
v-show,
v-bind。
正如你可能猜到的那样,Vue 自定义指令是 Vue 让我们为我们的项目构建额外指令的方式。它们是在整个项目中添加独特且可重用功能的好方法。
Vue 自定义指令可以操作元素以及处理 DOM 中的反应性。
在本中级教程结束时,您将了解:
-
什么是自定义指令
-
Vue 指令的各种事件钩子
-
如何创建自定义指令
现在是自定义指令时间!
什么是自定义指令
从本质上讲,自定义指令是使您的项目符合您的需求的一种方式。如果你使用 Vue 插件,你会注意到它们非常频繁地使用自定义指令。
例如,在v-lazy 插件,他们使用指令 v-lazy 来添加自定义功能,使图像加载更有效。在这里使用指令是最好的情况,因为我们想直接编辑 DOM。
你可能会问,”我不能只注册计算和观察程序等组件选项吗?"
是的。您可以。但是,虽然组件选项对于抽象和代码重用很有用,自定义指令仍然是最好的方法之一直接操作 DOM 元素。
但是,虽然组件选项对于抽象和代码重用很有用,自定义指令仍然是最好的方法之一直接操作 DOM 元素。
指令有五个钩子
就像组件及其生命周期钩子一样,每个 Vue 指令都有自己的钩子来触发
Vue 2 和 Vue 3 中的指令钩子是不同的。
以下是 Vue 2 指令钩子:
-
bind
– 当指令绑定到元素时调用一次 -
inserted
– 当绑定元素插入其父节点时 -
update
– 当元素更新时(但任何子项尚未更新) -
componentUpdated
– 在孩子们也更新之后 -
unbind
– 当指令与元素解除绑定时调用一次
以下是 Vue 3 指令钩子:
-
created
– 在应用元素的属性或事件侦听器之前调用。 -
beforeMount
– 与旧的绑定钩子相同 -
mounted
– 与旧的插入钩子相同 -
beforeUpdate
– 在元素本身更新之前调用(如生命周期钩子) -
updated
– 与旧组件相同更新的钩子 -
beforeUnmount
– 在卸载元素之前调用(如生命周期钩子) -
unmounted
– 与旧的 Unbind Hook 相同
在实现这些钩子时,它们各自都有一些它们接受的参数。
-
el
– 指令绑定到此元素;允许您修改它 -
binding
– 一个对象包含很多属性;我们稍后将深入探讨 -
vnode
– 虚拟节点 -
prevVnode
– 上一个虚拟节点(仅在更新钩子中可用)
重要说明Vue 指令文档是您应该将这些参数(除了 EL)视为只读,并且永远不要修改它们。
绑定对象
绑定对象包含多个属性,可帮助您实际向钩子添加功能。
-
name
– 指令名称(无前缀)v-
-
value
– 传递给指令的值 -
oldvalue
– 指令的上一个值(仅在更新钩子中可用) -
expression
– 绑定到字符串的表达式(例如,expression =v-direc=”3 * 3″
“3*3”
) -
arg
– 传递给字符串的任何参数(例如 V-direc:blue,arg = blue) -
modifiers
– 所有作为对象传递的修饰符(例如 V-direc.blue.link,修饰符 = {blue: true, link: true}
定义指令
在我们的文件中——或者无论你的 Vue 实例在哪里——我们只需要使用 Vue 2 中的方法或 Vue 3 中的方法。main.js
Vue.directive
app.directive
现在,让我们创建一个指令,允许我们操作组件的字体大小。它将被称为v-font-size。
在里面,我们将添加一些代码来监听 and 钩子并调整字体大小。main.js
beforeMount
updated
// Vue 2 Vue.directive("font-size", { bind: (el, binding) => { el.style.fontSize = 24 + "px"; }, updated: (el, binding) => { el.style.fontSize = 24 + "px"; }, }); // Vue 3 app.directive("font-size", { beforeMount: (el, binding) => { el.style.fontSize = 20 + "px"; }, updated: (el, binding) => { el.style.fontSize = 20 + "px"; }, });
从现在开始,我将使用 Vue 3 实现钩子,但如果需要,您可以将它们映射到上面的 Vue 2 钩子。
然后,在任何组件文件中,让我们添加以下两行,以便我们可以看到我们的组件的运行情况!每当我们声明一个指令时,我们都可以使用前缀 .v-
<p>Default Font Size</p> <p v-font-size>Modified Font Size</p>
还有另一种方法可以定义你的 Vue 指令。作为速记,您也可以在里面使用这种语法main.js
// pass a function! app.directive("font-size", (el, binding) => { el.style.fontSize = 24 + "px"; });
如果传递的是函数而不是对象,则它将在绑定和更新钩子期间运行。
我们有我们的第一个自定义指令在工作!现在,让我们把它做得更高级一些。
将参数传递给指令
有几种方法可以增加对指令的更多控制。这可以通过传递其他值、参数或修饰符来完成
在我们的示例中,假设我们希望更好地控制元素中的字体大小。
传递的值 – 用于反应式数据
传递数据最直观的方法是简单地为其提供一个值。这允许您的指令在值更改时响应式更新。这也提供了最灵活的控制,因为您可以接受各种值(任何字体大小)。
在您的组件中,声明将如下所示...
<p v-font-size='12'>Uses font-size directive</p> <!-- OR USE A VARIABLE --> <p v-font-size='fontSize'>Uses font-size directive</p>
在指令中,您需要更改方法以使用对象中的值。binding
app.directive('font-size', (el, binding, vnode) => { el.style.fontSize = binding.value + 'px' })
向指令发送参数
如果您真的不需要任何反应性,只是想要一种方法来为您的指令提供多个选项。争论是做到这一点的好方法。
指令中的代码是这样的。
app.directive('font-size', (el, binding, vnode) => { console.log(binding + ' ' + vnode) var size = 16 switch (binding.arg) { case 'small': size = 8 break case 'large': size = 32 break default: size = 16 break } el.style.fontSize = size + 'px' })
然后在我们的模板中。
<p v-font-size:small>Small</p> <p v-font-size:medium>Medium</p> <p v-font-size:large>Large</p>
使用修饰符
修饰符与参数相似,因为它们不适合反应性。但是当与参数结合使用时,您可以创建一个非常自定义的系统。
这是因为您可以在一个指令上应用多个修饰符。
让我们先在我们的指令中实现它们。和 的顺序仅取决于要优先处理哪些修饰符。if
else-if
Vue.directive("font-size", (el, binding, vnode) => { console.log(binding + " " + vnode); var defaultSize; if (binding.modifiers.small) { defaultSize = 12; } else if (binding.modifiers.large) { defaultSize = 32; } else { defaultSize = 16; } if (binding.modifiers.red) { el.style.color = "#ff0000"; } el.style.fontSize = defaultSize + "px"; });
然后我们可以在模板中使用它们
<p v-font-size.small.red>Small</p> <p v-font-size.medium>Medium</p> <p v-font-size.large>Large</p>
结论
恭喜!
你已经做到了这里,现在应该有一些注册你的 Vue 自定义指令的工作知识。
感谢您的关注,我希望本文为您提供构建一些出色工具所需的工具。
祝您编码愉快!
网友评论文明上网理性发言 已有0人参与
发表评论: