注册自定义指令的方式
注册v-focus自动聚焦指令:
<div id="app">
<input type="text" v-focus="msg">
</div>
1. 全局注册
Vue.directive("focus", {
// Vue会对html代码进行解析
// 解析之后,会将解析后的内容重新渲染到页面中
// inserted函数,就会在当前指令所在的元素,被插入到页面中的时候执行
inserted: function (el) {
// el 函数中接收的形参el,其实就是当前指令所在的元素
el.focus()
// console.log(el);
}
})
2. 局部注册
在创建Vue实例的时候,参数对象添加directives属性,在属性中注册指令即可!
全局注册所有的vue实例都能用
局部注册,只能在当前的vue实例中使用
const vm = new Vue({
el: "#app",
data: {
msg: "<h1>hello world</h1>"
},
directives: {
focus: {
inserted(el){
el.focus();
}
}
}
});
自定义指令的钩子函数:
directives: {
focus: {
// 当vue要对当前指令所在的元素进行解析的时候执行
bind(el){
console.log("bind 钩子函数被执行了")
},
// 当当前指令所在的元素被插入到页面中的时候,会执行的函数
inserted(el){
console.log("inserted 钩子函数被执行了")
// el.focus();
},
// 当当前指令绑定的数据,发生改变的时候,会执行update函数
update(el){
console.log("update 钩子函数被执行了")
},
// 当数据改变完成,元素更新完毕之后,会执行componentUpdated
componentUpdated(el){
console.log("componentUpdated 钩子函数被执行了")
},
// 当指令被卸载的时候
unbind(el){
console.log("unbind 钩子函数被执行了")
}
}
}
自定义指令的参数说明:
指令的使用语法:
v-bind:src="msg"
v-on:click="clickHandler"
v-on:click.stop=""
一个指令完整的写法:
指令名称:指令参数.修饰符="表达式"
在自定义指令中的钩子函数里,我们可以拿到和当前指令相关的所有的信息
指令名称:指令参数.修饰符="表达式"
<div id="app">
<input type="text" v-focus:shuaige.dashuaige.gaofushuai="msg">
</div>
Vue.directive("focus", {
bind(el, binding){
console.log(el);
console.log(binding);
// binding可以用来获取当前指令的所有的信息
// name: 获取的是当前指令的名称
// rawName: 带v的指令名称名称
// expression: 等号后面的表达式
// value: 这个是表达式的值
// arg: 获取到的就是指令的参数 冒号后面的内容
// modifiers: 指令的修饰符,这是一个对象,修饰符都会被作为属性存储到这个对象中,属性值是true
}
})
通过自定义指令来模拟v-text和v-html的功能
<!DOCTYPE html>
<html lang="en">
<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>
</head>
<body>
<div id="app">
<div v-mytext="msg"></div>
<div v-myhtml="msg"></div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.directive("mytext", {
bind(el, binding){
// 需求,就是将msg的值,赋值给当前元素的innerText属性
// msg的值: binding.value
// 当前元素: el
el.innerText = binding.value;
},
update(el, binding){
el.innerText = binding.value;
}
})
Vue.directive("myhtml", {
bind(el, binding){
// 需求,就是将msg的值,赋值给当前元素的innerText属性
// msg的值: binding.value
// 当前元素: el
el.innerHTML = binding.value;
},
update(el, binding){
el.innerHTML = binding.value;
}
})
const vm = new Vue({
el: "#app",
data: {
msg: "<h1>hello world</h1>"
}
});
</script>
</body>
</html>
自定义指令的简写形式:
Vue.directive("mytext", function(el, binding){
el.innerText = binding.value;
})
模拟v-on指令:
<!DOCTYPE html>
<html lang="en">
<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>
<style>
#parent{
width: 200px;
height: 200px;
background-color:pink;
}
#child{
width: 100px;
height: 100px;
background-color:hotpink;
}
</style>
</head>
<body>
<div id="app">
<div id="parent" v-myon:click.capture="parentClickHandler">
<div id="child" v-myon:click.stop="childClickHandler"></div>
</div>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//1. 注册一个指令 v-myon
Vue.directive("myon", {
bind(el, binding){
// 为当前元素注册指定类型的事件,事件处理函数为=后面的表达式代表的内容
// 当前元素: el
// 指定类型的事件: binding.arg
// 事件处理函数: binding.value
// capture: binding.modifiers.capture
// stop: binding.modifiers.stop
// el.addEventListener(事件名称, 事件处理函数, isCapture)
// el.addEventListener(事件名称, 事件处理函数, isCapture)
// el.addEventListener(binding.arg, function(e){
// binding.value(e);
// if(binding.modifiers.stop){
// e.stopPropagation();
// }
// })
el.addEventListener(binding.arg, function(e){
binding.value(e)
// if(binding.modifiers.stop){
// e.stopPropagation();
// }
}, binding.modifiers.capture)
}
})
const vm = new Vue({
el: "#app",
methods: {
childClickHandler(){
alert("子元素被点击了")
},
parentClickHandler(){
alert("父元素被点击了")
}
}
})
</script>
</body>
</html>