在vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称为指令系统
我们看到的v-
开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能
除了核心功能默认内置的指令 (v-model
和 v-show
),Vue 也允许注册自定义指令
自定义一个demo指令
注册一个自定义指令有全局注册与局部注册
全局注册主要是通过Vue.directive
方法进行注册
Vue.directive
第一个参数是指令的名字(不需要写上v-
前缀),第二个参数可以是对象数据,也可以是一个指令函数:
Vue.directive(id, definition)
传入的两个参数,id是指指令ID,definition是指定义对象。其中,定义对象可以提供一些钩子函数。
<div id="app">
<!-- input输入框获得焦点 -->
<input type="text" v-focus/>
</div>
<script>
// 注册一个全局自定义指令 v-focus
Vue.directive("focus", {
// 当被绑定的元素插入到 DOM 中时……
inserted(el, binding) {
// 聚焦元素
el.focus(); // 页面加载完成之后自动让输入框获取到焦点的小功能
}
})
</script>
局部注册通过在组件options选项中设置directive
属性
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus() // 页面加载完成之后自动让输入框获取到焦点的小功能
}
}
}
<div id="app">
<p v-demo:red="msg">{{msg}}</p>
</div>
<script>
// 全局指令
Vue.directive('demo', function (el, binding) {
console.log(el) //p标签
console.log(binding) //输出的是一个对象obj
console.log('指令名:'+binding.name)//指令名
console.log('指令的绑定值:'+binding.value)//指令的绑定值
console.log('绑定值的字符串形式:'+binding.expression) //绑定值的字符串形式
console.log('传给指令的参数:'+binding.arg)//传给指令的参数
})
var vm = new Vue({
el: "#app",
data: {
msg: 'hello!'
},
// 局部指令
directives:{
demo:{
inserted: function (el) {
console.log(el)
}
}
}
})
</script>
对象字面量
<div id="app">
<p v-demo="colours">{{colours.text}}</p>
</div>
<script>
Vue.directive('demo', function (el, binding) {
console.log(el) // p标签
console.log(binding) // 输出的是一个对象obj
console.log(binding.value) // {color: 'blue',text: 'hello!'}
console.log(binding.value.color) // 'blue'
console.log(binding.value.text) // 'hello!'
el.style = 'color:' + binding.value.color
})
var vm = new Vue({
el: "#app",
data: {
colours: {
color: 'blue',
text: 'hello!'
}
}
})
</script>
生命周期钩子
指令定义函数提供了几个钩子函数(可选):
bind
:只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。inserted
:被绑定元素插入父节点(div#app
)时调用(父节点存在即可调用,不必存在于document中)。update
:当绑定指令的元素(VNode-虚拟节点)状态发生改变时触发(包括样式、内容、vue数据…)componentUpdated
:指令所在的组件的VNode以及其子VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑(元素从DOM中删除)时调用。
<div id="app">
<p v-demo="color">{{num}}</p>
<button @click="add">增加</button>
<button onclick='unbind()'>解绑</button>
</div>
<script>
function unbind() {
vm.$destroy(); //另外起一个方法解绑
}
Vue.directive('demo', { //五个注册指令的钩子函数
bind: function () { //1.被绑定
//做绑定的准备工作。比如添加事件监听器,或是其他只需要执行一次的复杂操作
console.log('1 - bind');
},
inserted: function () { //2.绑定到节点
console.log('2 - inserted');
},
update: function () { //3.组件更新
//根据获得的新值执行对应的更新。对于初始值也会调用一次
console.log('3 - update');
},
componentUpdated: function () { //4.组件更新完成
console.log('4 - componentUpdated');
},
unbind: function () { //5.解绑
//做清理操作。比如移除bind时绑定的事件监听器
console.log('5 - bind');
}
})
var vm = new Vue({
el: "#app",
data: {
num: 10,
color: 'red'
},
methods: {
add: function () {
this.num++;
}
}
})
</script>
初始化触发方法1和2,点击增加按钮触发方法3和4,点击解绑按钮触发方法5,如下图: