【Vue | 补洞 | 10】自定义指令

通过自定义指令,实现对 Dom 元素的操作封装和复用!

1. 作用

对 Dom 元素的操作进行封装和复用

​  举例来说,如常见的内置指令v-on用于绑定 Dom 元素上的事件;v-bind绑定 Dom 元素上的属性等。当我们希望自定义一个指令去操作Dom时,就需要用到自定义指令函数


2. 写法

1)函数写法

  1. 代码实现
// 写法1:函数
<template>
	<h2 v-jokerls="n"></h2>
</template>

<script>
export default {
	directives: {
    // element: 真实DOM元素
    // binding: 指令绑定元素的信息
  		jokerls(element, binding) {
        	// binding.value 相当于 v-jokerls="n" 中的 "n"
    		element.innerText = binding.value
    	}
  }
}
</script>
  1. 被调用的时机

    • 元素与指令 初次成功绑定时

    • 指令所在的模板被 重新解析

  2. 注意

    • 元素与指令成功绑定时,真实Dom 还未渲染到页面上,因此调用如 element.focus 的方法会不生效
    • 只有在把 Dom 真正放入页面时调用 element.focus 方法才能生效,函数式写法无法满足,因此需要参考 对象写法

2)对象写法

  1. 代码实现
<script>
export default {
	directives: {
        自定义指令名: {
            bind(element, binding){
            element.value = binding.value
          },

          inserted(element, binding) {
            element.focus()
          },

          update(element, binding) {
            // 注意!update中要赋最新值,不然在数据更新后,该节点的数据仍然是旧的
            element.value = binding.value
          }
        }
  	}
}
</script>
  1. 被调用的时机

    • bind:指令与元素成功绑定

    • inserted:指令所在元素被放入页面后(此时已有真实DOM

    • update:指令所在模板被重新解析

    如上调用时机对应的原生Dom操作代码如下:

    const input = document.createElement('input')
    
    // bind 阶段
    input.className = 'xxx'
    input.value = 'xxx'
    
    // 将元素插入页面
    document.body.appendChild(input)
    
    // 元素被插入页面后 inserted
    input.focus()
    

3. 注意

1)不能使用驼峰写法

// 错误!
<span v-bigNumber='xxx'>
  
// 正确
<span v-big-number='xxx'>
    
new Vue({
	directives: {
    // 函数写法
  	'big-number': function(element, binding){
  		...
  	}
  
  	// 对象写法
  	'big-number'(element, binding) { ... }
  }  	
})

2)指令中的钩子函数,this 指向了 window

directives: {
	自定义指令名() {
		console.log(this) // -> Window
	}
}  

3)指令默认只存在于当前实例,若要注册全局指令见下:

// 1.局部指令
new Vue({
	directives: {
  	...
  }
})
// 2.1 全局指令-对象(与全局过滤器 Vue.filter 一样)
Vue.directive('自定义指令名', {
	bind() {...},
    inserted() {...},
    update() {...}
})

// 2.2 全局指令-函数
Vue.directive('自定义指令名', function(element, binding){
	...
})

4)函数写法 & 对象写法区别

  • 函数:只调用了 bindupdate(因为大部分情况下,bind 和 update 中的逻辑是一样的,都需要赋值新的值,因此函数写法实则是提供了一种简写的形式
  • 对象:可以自定义配置 bind、inserted、update 三个钩子函数,分别在不同时机触发

4. 总结

  • 通过 directives 配置项,或 Vue.directive API 来注册自定义指令
  • 函数写法只调用了 bind 和 update 钩子函数;而对象写法可以灵活配置 bind、inserted、update 三个钩子函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值