前言
一、Vue的自定义指令分为?
vue中除了核心功能内置的指令外,也允许注册自定义指令。有的情况下,对普通DOM元素进行底层操作,这时候就会用到自定义指令。
自定义指令分为全局自定义指令和局部的自定义指令
全局自定义指令
是通过Vue.directive(‘第一个参数是指令的名称’,{第二个参数是一个对象,这个对象上有钩子函数})
下边举例说明:
Vue.directive('focus', {// el:指令所绑定的元素,可以用来直接操作 DOM。//binding:一个对象,包含以下 property:inserted: function (el) {// inserted 表示被绑定元素插入父节点时调用el.focus();}});
局部自定义指令
局部注册通过在组件options选项中设置directive属性
是定义在组件内部的,只能在当前组件中使用
下边举例说明:
directives: {// 指令名称dir1: {inserted(el) {// 指令中第一个参数是当前使用指令的DOMconsole.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:只调用一次,指令与元素解绑时调用。
项目中:拖拽
三、自定义指令的应用场景
使用自定义组件组件可以满足我们日常一些场景,这里给出几个自定义组件的案例:
1.防抖
2.图片懒加载
3.一键 Copy的功能
二、 vue自定义指令的应用场景
使用自定义指令背景
代码复用和抽象的主要形式是组件。
当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令
但是,对于大幅度的 DOM 变动,还是应该使用组件
常用案例
1、 输入框自动聚焦
// 注册一个全局自定义指令 `v-focus`Vue.directive('focus', {// 当被绑定的元素插入到 DOM 中时inserted: function (el) {// 聚焦元素el.focus()}})<input v-focus>
2 下拉菜单
点击下拉菜单本身不会隐藏菜单
点击下拉菜单以外的区域隐藏菜单
Vue.directive('clickoutside', {bind(el, binding) {function documentHandler(e) {if (el.contains(e.target)) {return false }if (binding.expression) {binding.value(e)}}el.__vueMenuHandler__ = documentHandlerdocument.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__}})