directives
vue官方文档 有一些内置指令:v-if, v-for, v-show, v-html等等
1. 指令的作用
- 主要用于DOM操作
- vue实例/组件用于数据绑定、事件监听、dom更新
- vue指令主要目的是原生dom操作
- 减少重复
- 如果某个dom操作经常使用,可以封装为指令
- 如果某个dom操作比较复杂,也可以封装为指令
- 位置 写在main.js里, new Vue()之前。
2. 指令用法
- 自己造一个指令,v-x,要求点击出现x。
- 可以造全局指令,也可以局部指令。
全局指令
语法:
Vue.directive('dirName',directiveOptions)
//main.js里
Vue.directive("x",{
inserted: function (el){
el.addEventListener("click",()=>{
console.log("x")
})
}
})
// 在需要应用的地方
<img src="xxx" v-x>
局部指令
语法
new Vue({
directives:{
dirName:{
directiveOptions
}
}
});
//在组件vue的export default里面写,再需要的地方加上V-X
export default{
name:xxx,
directives:{
"x": {
inserted(el){
el.addEventListener('click', ()=>{console.log('xx'})
}
}
}
}
// 只能在该实例里用v-x
3. directiveOptions
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
-
bind(el,binding,vnode,oldVnode):只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。类似于created
-
inserted(el,binding,vnode,oldVnode):被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。类似于mounted.
-
update(el,binding,vnode,oldVnode):所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。类似于updated.
-
componentUpdated(el,binding,vnode,oldVnode):指令所在组件的 VNode 及其子 VNode 全部更新后调用。
-
unbind(el,binding,vnode,oldVnode):只调用一次,指令与元素解绑时调用。类似于destoryed.
这是一个使用了这些 property 的自定义钩子样例:
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
4. 自定义一个on指令
new Vue({
directives: {
on2: {
// bind 可以改为 inserted
bind(el, info) {
el.addEventListener(info.arg, info.value);
// Vue 自带的 v-on 并不是这样实现的,它更复杂,用了事件委托
},
unbind(el, info) {
el.removeEventListener(info.arg, info.value);
}
}
},
template: `
<button v-on2:click="hi">点我</button>
`,
methods: {
hi() {
console.log("hi");
}
}
}).$mount("#app");
5. 写一个自定义指令 v-y,做到点击元素就打印 'y'
codesandbox.io/s/delicate-… main.js
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.directive("y", {
inserted: function(el) {
el.addEventListener("click", () => {
console.log("y");
});
}
});
new Vue({
render: h => h(App)
}).$mount("#app");
app.vue
<template>
<div id="app">
<button v-y>输出y</button>
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: "App",
components: {
HelloWorld
}
};
</script>