19. Vue 自定义指令

需求

19. Vue 自定义指令

可以看到上面的输入框在刷新页面并没有进行自动聚焦,那么这时候可以使用自定义一个focus()方法来处理。还有能否在刷新页面的时候,可以设置value在文本框中以及设置字体颜色呢?能否进而通过传参的方式设置字体颜色呢?

这些都可以基于Vue的自定义指令来实现。

简介[1]

除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

对于上面的需求,则需要自定义一个聚焦的focust方法。

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

<input v-focus>

在上面定义自定义指令中,使用了inserted这个钩子函数,另外还有更多的钩子函数。

钩子函数[2]

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,「但是可能发生在其子 VNode 更新之前」。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。

  • componentUpdated:指令所在组件的 VNode 「及其子 VNode」 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

bind:在列表中初始化输入框的值以及字体样式

「bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。」一般bind只会去处理元素的样式、值等属性,不会去处理js函数,因为有很多js函数需要插入dom内存中才可以处理,而bind在之前,导致js函数执行失败。可以考虑bind是执行在window.onload之前的行为。

        directives: {
focus: {
bind: function (el) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意:在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
// 因为,一个元素,只有插入DOM之后,才能获取焦点
// el.focus()

// 在绑定元素的时候,可以设置初始化的值
el.value = 'bind func';
el.style.color = 'blue';
el.style.fontWeight = '700';
},

在这里focus()方法是一个js行为,需要元素插入dom内存中才有效,所以,在这里,我只设置了元素内容以及样式。

inserted:在列表中实现该聚焦focus需求

「inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】」一般inserted方式是在bind方法之后,类似windows.onload加载完毕之后,所以相关执行的js方法都是放到inserted来进行处理。

首先在VM中注册一个局部指令,如下:

19. Vue 自定义指令

在输入框上,设置自定义v-focus指令,如下:

19. Vue 自定义指令

刷新页面,显示如下:

19. Vue 自定义指令

可以从页面看到,输入框既执行了bind方法,也执行了inserted方法。

其中,上面我在写bind钩子函数的时候,写死了字体颜色,那么能否通过参数化,将参数传递进去呢?

接下来我们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。

钩子函数参数[3]

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM 。
  • binding:一个对象,包含以下属性:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

看了上面官网介绍的这些「钩子函数参数」我是比较迷糊的,不过,没关系。下面写个示例打印一下信息,就知道大概是怎么回事了。

打印钩子函数的参数信息

这个打印信息,我主要打印这几个常用的参数,用来刚才上面如何设置输入框的字体颜色。

  • binding:一个对象,包含以下属性:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"

首先,我给自定义命令设置一个绑定的值,如下:

19. Vue 自定义指令
<input v-focus="'green'"

注意:我设置里面的是一个字符串'green',因为后续我要用来设置样式。

首先打印一下这三个参数会显示什么内容来看看。

19. Vue 自定义指令

浏览器打印信息如下:

19. Vue 自定义指令

那么下面只要基于提供的绑定值,就可以设置样式的字体颜色了,如下:

19. Vue 自定义指令

刷新浏览器,如下:

19. Vue 自定义指令

函数简写[4]

在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})

这是全局自定义指令的写法, 下面这是局部自定义指令的写法,如下:

首先绑定一个自定义指令v-fontsize在元素上。

19. Vue 自定义指令

然后定义简写的自定义指令,如下:

19. Vue 自定义指令
        directives: {
'fontsize': function (el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
el.style.fontSize = parseInt(binding.value) + 'px'
},
'focus': {
bind: function (el,binding) { // 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
// 注意:在每个 函数中,第一个参数,永远是 el ,表示 被绑定了指令的那个元素,这个 el 参数,是一个原生的JS对象
// 在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用
// 因为,一个元素,只有插入DOM之后,才能获取焦点
// el.focus()
...

浏览器显示效果如下:

19. Vue 自定义指令

Reference

[1]

简介: https://cn.vuejs.org/v2/guide/custom-directive.html#%E7%AE%80%E4%BB%8B

[2]

钩子函数: https://cn.vuejs.org/v2/guide/custom-directive.html#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0

[3]

钩子函数参数: https://cn.vuejs.org/v2/guide/custom-directive.html#%E9%92%A9%E5%AD%90%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0

[4]

函数简写: https://cn.vuejs.org/v2/guide/custom-directive.html#%E5%87%BD%E6%95%B0%E7%AE%80%E5%86%99


交流QQ群:

19. Vue 自定义指令

19. Vue 自定义指令


点击下面,查看更多Vue系列文章

19. Vue 自定义指令19. Vue 自定义指令


19. Vue 自定义指令



原文始发于微信公众号(海洋的渔夫):19. Vue 自定义指令

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/32100.html

(1)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!