(十三)vue之自定义指令

1.简介

除了核心功能默认内置的指令 (v-model 和 v-show)Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
可以说组件是对UI层的复用,自定义指令是控制层与行为层的复用

2.指令的注册

自定义指令和组件注册的方法很相似,也分为全局注册和局部注册。
全局注册指令(和全局注册一样)
把全局注册时的component单词换成directive即可

Vue.directive("指令名",{
//指令内容
})

局部注册指令(和局部注册一样)
在vue或者组件实例中添加directives选项即可

//vue实例
let vueApp = new Vue({
el: "#app",
directives: {
dire1: {}, //声明指令dire1
dire2: {}, //声明指令dire2
dire3: {}, //声明指令dire3
}
});

3.自定义指令中的钩子函数

概念
和组件具有生命周期钩子函数一样,指令也具有生命周期钩子函数,你可以在不同的钩子函数里面进行不同的操作。比如:在指令与元素绑定时执行什么,在指令与元素解绑时又执行什么。

具体的钩子函数(指令的生命周期内)

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

注意
这些钩子函数在指令实现中都是可选的,并不是一定都要给上,然后我们的指令实现代码一般都是放在这些钩子函数中进行执行。

4.使用示例

以下展现了自定义指令的【注册方式+钩子函数基本使用】
在这里插入图片描述

注意:
1.在自定义指令使用时会加上v-前缀,表示是vue的自定义指令,但是在我们定义时不需要加上
2.自定义指令名称合法即可
3.你的指令实现代码写到那个构造函数中,那么就会在其对应时刻执行

//指令内容:将实现写在inserted钩子函数中,表示input插入到了父节点就自动聚焦
inserted: function (el) {
el.focus(); //自定获取焦点
}

5.各钩子函数概览

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input v-focus v-model="val" />
<test :val="val"></test>
</div>
<script>
//注册全局的自定义指令
Vue.directive("focus", {
bind: function (el) {
alert("bind :自定义指令第一次绑定到元素上");
},
inserted: function (el) {
alert("inserted :被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。");
},
update: function (el) {
alert("Update: 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有");
},
componentUpdated: function (el) {
alert("componentUpdate :指令所在组件的 VNode 及其子 VNode 全部更新后调用");
},
unbind: function (el) {
alert("Unbind :指令与元素解绑时调用");
}
})
Vue.component("test", {
props: ["val"],
template: `<div>{{val}}</div>`,
});
//vue实例
let vueApp = new Vue({
el: "#app",
data: {
val: "123456",
}
});
</script>
</body>
</html>

6.钩子函数参数

前面我们看到了,在inserted构造函数中接受了一个参数el, 他表示当前指令绑定的元素。实际上还有其他参数。
然后由于我们的所有代码都是写在各个构造函数里面的,所以我们必须明白钩子函数的几个参数。

参数详情

大致有四个参数: el , binding , vnode , oldVnode.
这几个参数是对位传参,根据位置来判断,命名合法就行。

1.el: 表示指令所绑定的元素,可用来直接操作DOM
2.binging: 一个绑定对象,主要的属性如下:

binding = {
name: "指令名。这是你定义时的名字",
rawName: "指令实际使用时的名字",
expression: "指令绑定的表达式名称",
value: "指令绑定的表达式的真正的值,即expresion这个表达式对应的值",
modifiers: "指令在使用时如果添加了修饰符的话,这就表示修饰符集合对象,比如stop"
oldValue: "指令绑定的表达式的上一个值,仅在update和componentUpdate钩子中可用",
arg: "传给指令的参数。例如,对与v-on:click=”fn”而言,click就是参数",
}

这些属性并不是在每一个钩子函数的binging参数里都有,要看实际使用时是否含有值。
3.Vnode: vue编译生成的虚拟节点,后面介绍
4.oldVnode: 上一个虚拟节点,仅在update和componentUpdate钩子中可用

注意
除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。(直接放到el元素对象上)

7.函数简写

在很多时候,你可能想在 bindupdate 时触发相同行为,而不关心其它的钩子。比如这样写:

Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

实例:下面两种方式实现效果是一样的,但是第二种会在 bindupdate 时都触发
在这里插入图片描述

8.自定义指令绑值

如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。
这意味着我们可以通过,指令绑定的表达式值与值不同做出不同的响应
这里绑定的是对象字面量(也可以直接绑定vue实例对象中的数据)

<div v-demo="{ color: 'white', text: 'hello!' }"></div>

在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值