vue directive 指令开发

为什么要写指令?

directive 和 component 的区别是什么?

指令适合处理简单的数据和对DOM的一些操作,v-focus,v-touch这种行为的一些操作适合用指令去实现。

涉及到复杂的行为,尤其是要接受各种选项的,那么就适合在 component 中去实现

https://github.com/vuejs/vue/issues/862

全局指令

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

局部指令

组件中设置一个 directives 的选项

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

全局指令插件写法

!function () { 
    let vueLazy = {}; 

    // options vue.use(xxx,{}) 传入额外参数
    vueLazy.install = function (Vue, options) { 
        Vue.directive('lazy', { 
            bind(el, binding) { 

            }, 
            update(el, binding) { 

            }, 
            unbind(el) { 

            } 
        }); 
    }; 

    if (typeof exports == "object") { 
        module.exports = vueLazy; 
    } else if (typeof define == "function" && define.amd) { 
        define([], function () { 
            return vueLazy 
        }); 
    } else if (window.Vue) { 
        window.vueLazy = vueLazy; 
        Vue.use(vueLazy); 
    } 
}();

执行周期-钩子函数

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

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

Gif展示这5个的执行策略

html部分

<button @click="clickMe">click</button> 
<div class="block" v-lazy:class="className" v-if="status"> 
    father className 
    <div v-if="status2"> 
        child 
    </div> 
</div>

Js 部分

new Vue({ 
    el: '#demo', 
    data: function () { 
        return { 
            className: 'customClass', 
            imgSrc: 'https://raw.githubusercontent.com/github/explore/6c6508f34230f0ac0d49e847a326429eefbfc030/topics/gulp/gulp.png', 
            status: false, 
            status2: false 
        } 
    }, 
    methods: { 
        clickMe() { 
            this.status = !this.status; 
            setTimeout(()=> { 
                this.status2 = !this.status2 
            },2000); 
        } 
    } 
})