Vue | 21 可复用性&组合-自定义指令

内容提要:

  1. 自定义指令基本用法介绍
  2. 自定义指令内部包含哪些钩子函数
  3. 指令钩子内部传递哪些元素值
  4. 自定义指令函数的缩略写法用例
  5. 在JavaScript对象中传递多个字面值

介绍

除了在核心附带的默认的指令集合(v-modelv-show)外,Vue也允许你注册自定义指令。注意在Vue 2.0,代码重用和抽象的主要形式是组件-然而,可能某些情况下你可能需要针对原生元素进行一些底层的DOM访问,这就是定制元素仍然有用的地方,一个例子是聚焦一个输入框,像这样:

input

当页面加载的时候,元素获得焦点(注意:autofocus在手机的Safari上无效)。实际上,如果你访问本页后没有点击任何其他的地方,上面的输入框应用获得焦点。现在让我们构建指令实现这个:

// 注册一个全局的自定义指令称为“v-focus”
Vue.directive('focus', {
    // 当绑定到元素插入到DOM时
    inserted:function (el) {
        // 焦点元素
        el.focus()
    }
})

如果你想注册一个局部指令,组件页接受directives 操作项:

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

在模板内,你能在任何元素使用v-focus属性,像这样:

<input v-focus>

钩子函数

一个指令定义对象能够提供一些钩子函数(所有的都是可选):

  • bind:仅被调用一次,当指令第一次绑定到元素时,在这里,你可以做一些一次性设置工作

  • inserted:当组件元素被插入到父节点的时候调用(这只保证父节点的存在,不一定在文档中)。

  • update:包含组件的VNode被更新之后调用,但可能在它的子组件更新之前更新。指令的值可能改变也可能不变,但你能跳过不需要的更新通过对比当前的绑定值和旧值(参见下面的钩子参数)。

    我们稍后later将更详细的介绍VNodes,当我们渲染函数的时候 render functions

  • componentUpdated:包含组件的VNode和它的子组件的VNodes被更新之后调用。

  • unbind: 仅仅被调用一次,当指令从元素解绑是调用。

通过这些钩子我们可以查询如下属性(例如:elbindingvnode,和oldVnode)在下一节。

指令钩子元素

指令钩子传递这些元素:

  • el:指令绑定到的元素。这可以用来直接操作DOM。
  • binding:包含以下属性的对象。
    • name:指令的名字,不带v-前缀
    • value:被传递给指令的值。例如在v-my-directive=“1 + 1”,值是2
    • oldValue:旧值,仅在updatecomponentUpdated可用。无论值改变与否它都可用。
    • expression:作为一个字符串绑定给表达式。例如在v-my-directive=“1 + 1”,表达式是“1 + 1”.
    • arg:传递给指令的参数(如果有的话),例如v-my-directive:foo,参数是“foo”
    • 修饰符:包含修饰符的对象(如果有的话,例如在v-my-directive.foo.bar,修饰符对象是{ foo: true, bar: true }.
  • vnode: 通过Vue的编译器产生的虚拟node。详看 VNode API
  • oldVnode:前一个虚拟node,仅在updatecomponentUpdated钩子可用。

除了el之外,你要以只读的方式对待这些参数,并且不要修改。如果你需要通过钩子分享信息,我们建议你通过元素的dataset操作.

使用这些属性的自定义指令的例子:

<div id="hook-arguments-example" v-demo: foo.a.b="message"></div>
Vue.directive('demo',{
    bind: function (el, binding, vnode) {
        var s = JSON.stringify
        el.innerHTML = 
            'name:' + s(binding.name) + '<br>' +
            'value:' + s(binding.value) + '<br>' + 
            'expression:' + s(binding.expression) + '<br>'
            'argument:' + s(binding.arg) + '<br>' + 
            'modifiers:' + s(binding.modifiers) + '<br>' + 
            'vnode keys:' + Object.keys(vnode).join(', ')
    }
})

new Vue({
    el: '#hook-arguments-example',
    data: {
        message: 'hello!'
    }
})

directive

函数简写

许多情况下,你可能想让bindupdate有相同的行为,但不关心其它的行为,例如:

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

对象字面值

如果你的指令需要多个值,你也能够在一个JavaScript对象的字面值中传递。记住,指令能携带任何有效的JavaScript表达式。

<div v-demo="{ color: 'white', text: 'hello!'}"></div>
Vue.directive('demo', function (el, binding) {
    console.log(binding.value.color) // => "white"
    console.log(binding.value.text)   // => 'hello!'
})

猜你喜欢

转载自blog.csdn.net/wudizhanshen/article/details/85332145