Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 进阶 ------- 自定义指令 #11

Open
Corbusier opened this issue Jun 8, 2017 · 0 comments
Open

Vue 进阶 ------- 自定义指令 #11

Corbusier opened this issue Jun 8, 2017 · 0 comments
Labels

Comments

@Corbusier
Copy link
Owner

简介

除了默认设置的核心指令v-modelv-show,Vue允许注册自定义指令。代码复用的主要形式和抽象是组件,有的情况下还是要对DOM元素进行底层操作,这时需要用到自定义指令。以下例子中可以聚焦一个input元素:

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

以上的代码可以在元素加载时,input将获得焦点。也可以使用局部注册,组件中接收directives的选项:

    /*在模板中任何元素上使用新的v-focus属性*/
    <input v-focus>
    
    components:{
        directives: {
            focus: {
            //指令的定义---
            }
        }    
    }

钩子函数

指令定义函数提供了几个钩子函数(可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。这个钩子函数可以定义一个绑定时执行一次的初始化动作。
  • update:被绑定元素所在的模板更新时调用,不论绑定值是否变化。通过比较前后的绑定值,可以忽略不必要的模板更新(详细的钩子函数参数见下)。
  • inserted:被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
  • componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
  • unbind:只调用一次,指令与元素解绑时调用。

钩子函数参数

钩子函数被赋予以下的参数:

  • el:指令所绑定的元素,可以用来直接操作DOM。

  • binding:一个对象,包含以下属性:

    • name:指令名,不包括v-前缀。

    • value:指令的绑定值,例如:v-my-directive="1 + 1",value的值是2

    • oldValue:指令绑定的前一个值,仅在updatecomponentUpdated钩子中可用。无论值是否改变都可用。

    • expression: 绑定值的字符串形式。例如v-my-directive="1 + 1",expression 的值是 1 + 1

    • arg: 传给指令的参数。例如v-my-directive:foo,arg的值是foo

    • modifiers: 一个包含修饰符的对象。例如:v-my-directive.foo.bar,修饰符对象 modifiers 的值是{ foo: true, bar: true }

  • vnode:Vue编译时生成的虚拟节点。

  • oldVnode:上一个虚拟节点,仅在updatecomponentUpdated钩子中可用。

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

一个使用了这些参数的自定义钩子样例:

    <div id="hook-arguments-example" v-demo:hello.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!'
        }
    })

函数简写

大多数情况下,我们可能想在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!"
    })
@Corbusier Corbusier added the Vue label Jun 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant