全局自定义指令:vue.directive(’第一个参数是指令名称‘,{第二个参数是一个对象,这个对象有钩子函数})
Vue.directive('focus', { // el:指令所绑定的元素,可以用来直接操作 DOM。 //binding:一个对象,包含以下 property: inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用 el.focus(); } });
局部自定义指令:
局部自定义指令通过组件options选项中设置directive属性,是定义在组件内部的,只能在当前组件中使用
directives: { // 指令名称 dir1: { inserted(el) { // 指令中第一个参数是当前使用指令的DOM console.log(el); console.log(arguments); // 对DOM进行操作 el.style.width = '200px'; el.style.height = '200px'; el.style.background = '#000'; } }, color: { // 为元素设置指定的字体颜色 bind(el, binding) { el.style.color = binding.value; } } }
自定义指令的钩子函数
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用
可以在项目中实现拖拽时使用自定义指令
自定义指令应用场景:防抖 图片懒加载 一键copy的功能
vue自定义指令应用场景:
输入框自动聚焦
// 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时 inserted: function (el) { // 聚焦元素 el.focus() } }) <input v-focus>
下拉菜单(点击下拉菜单本身不会隐藏菜单,但是我们现在需要实现隐藏菜单)
Vue.directive('clickoutside', { bind(el, binding) { function documentHandler(e) { if (el.contains(e.target)) { return false } if (binding.expression) { binding.value(e) } } el.__vueMenuHandler__ = documentHandler document.addEventListener('click', el.__vueMenuHandler__) }, unbind(el) { document.removeEventListener('click', el.__vueMenuHandler__) delete el.__vueMenuHandler__ } }) new Vue({ el: '#app', data: { show: false }, methods: { handleHide() { this.show = false } } }) <div class="main" v-menu="handleHide"> <button @click="show = !show">点击显示下拉菜单</button> <div class="dropdown" v-show="show"> <div class="item"><a href="#">选项 1</a></div> <div class="item"><a href="#">选项 2</a></div> <div class="item"><a href="#">选项 3</a></div> </div> </div>
相对时间转换(类似微博、朋友圈发布动态后的相对时间)
<span v-relativeTime="time"></span> new Vue({ el: '#app', data: { time: 1565753400000 } }) Vue.directive('relativeTime', { bind(el, binding) { // Time.getFormatTime() 方法,自行补充 el.innerHTML = Time.getFormatTime(binding.value) el.__timeout__ = setInterval(() => { el.innerHTML = Time.getFormatTime(binding.value) }, 6000) }, unbind(el) { clearInterval(el.innerHTML) delete el.__timeout__ } })