20-Vue核心-自定义指令
回顾一下前面学习的,Vue模板语法
1)插值语法
功能:用于解析标签体内容
写法:{{xxx}},xxx是js表达式,并且可以直接读取到data中的所有属性
2)指令语法
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件...)
举例:v-bind:href="xxx" 或 :href="xxx",xxx同样要写js表达式
备注:Vue中有很多的指令,且形式都是:v-????,此处我们只是拿v-bind举个例子
我们知道,指令语法主要是用于解析标签的,那自定义指令自然也离不开这个范畴
回顾一个DOM操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button id="btn">生成输入框</button>
<script type="text/javascript">
const btn = document.getElementById("btn")
btn.onclick = ()=>{
const input = document.createElement("input")
// 设置 input 的类名
input.className = "demo"
// 设置初始值
input.value = 100
// 点击事件,跳出弹窗
input.onclick = ()=>{
alert(1)
}
document.body.appendChild(input)
// 获取焦点
input.focus()
console.log(input.parentElement)
input.parentElement.style.backgroundColor = "skyblue"
}
</script>
</body>
</html>

自定义指令directives
除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。
1)局部指令的定义语法
函数式写法:
指令名(element,binding)
element表示获取当前真实的DOM节点
binding表示要绑定的对象,包含以下属性: name value oldValue expression arg modifiers
函数式写法的回调函数,什么时候会被调用(相当于对象式写法的 bind 和 update 回调函数)
- 指令与元素成功绑定时(一上来)
- 指令所在的模板被重新解析时
new Vue({ // 自定义指令 directives:{ // 1.函数式写法 big(element,binding){ // 这里可以通过 element instanceof HTMLElement ,判断 element 是否是 HTMLElement 的实例对象 console.log(element instanceof HTMLElement) // true console.log(binding) } } })
对象式写法:
指令名:{
bind(element,binding){},
inserted(element,binding){},
update(element,binding){}
}
bind(element,binding)回调函数:指令与元素成功绑定时调用
inserted(element,binding)回调函数:指令所在元素被插入页面时调用
update(element,binding)回调函数:指令所在模板结构被重新解析时调用
new Vue({ // 自定义指令 directives:{ // 2.对象式写法 fbind:{ // bind(element,binding)回调函数,指令与元素成功绑定时调用 bind(element,binding){ console.log("bind") }, // inserted(element,binding)回调函数,指令所在元素被插入页面时调用 inserted(element,binding){ console.log("inserted") }, // update(element,binding)回调函数,指令所在模板结构被重新解析时调用 update(element,binding){ console.log("update") } } } })
这里需要注意:
a)定义指令时不加 v-,但使用时要加 v-
b)指令名如果是多个单词,要使用 big-number 命名方式,不要用 bigNumber 命名
这是因为无法识别大小写,会把 bigNumber 识别成 bignumber,一定要使用函数的完整形式,"big-number":function(element,binding){}
局部指令的完整写法:
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
-->
<!--准备好一个容器-->
<div id="root">
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大十倍后的n值是:<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
</div>
<script type="text/javascript">
// 阻止 vue 在启动时生成生产提示
Vue.config.productionTip = false
new Vue({
el:"#root",
data(){
return{
n:1
}
},
// 自定义指令
directives:{
// 1.函数式写法,定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
// element 获取当前真实的DOM节点
// binding 要绑定的对象,包含以下属性: name value oldValue expression arg modifiers
// big函数什么时候会被调用(相当于对象式写法的 bind 和 update 回调函数)
// 1)指令与元素成功绑定时(一上来)
// 2)指令所在的模板被重新解析时
big(element,binding){
// 这里可以通过 element instanceof HTMLElement ,判断 element 是否是 HTMLElement 的实例对象
console.log(element instanceof HTMLElement) // true
console.log(binding)
element.innerText = binding.value * 10
},
// 2.对象式写法,定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
fbind:{
// bind(element,binding)回调函数,指令与元素成功绑定时调用
bind(element,binding){
console.log("bind")
element.value = binding.value
},
// inserted(element,binding)回调函数,指令所在元素被插入页面时调用
inserted(element,binding){
console.log("inserted")
element.focus()
},
// update(element,binding)回调函数,指令所在模板结构被重新解析时调用
update(element,binding){
console.log("update")
element.value = binding.value
}
}
}
})
</script>
</body>
</html>

2)全局指令的定义语法
// 自定义指令 // 1.函数式写法 Vue.directive("big",function(element,binding){ // 这里可以通过 element instanceof HTMLElement ,判断 element 是否是 HTMLElement 的实例对象 console.log(element instanceof HTMLElement) // true console.log(binding) element.innerText = binding.value * 10 }) // 2.对象式写法 Vue.directive("fbind",{ // bind(element,binding)回调函数,指令与元素成功绑定时调用 bind(element,binding){ console.log("bind") element.value = binding.value }, // inserted(element,binding)回调函数,指令所在元素被插入页面时调用 inserted(element,binding){ console.log("inserted") element.focus() }, // update(element,binding)回调函数,指令所在模板结构被重新解析时调用 update(element,binding){ console.log("update") element.value = binding.value } })
全局指令的完整写法:
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义指令</title>
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<!--
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点
-->
<!--准备好一个容器-->
<div id="root">
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>放大十倍后的n值是:<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
<hr/>
<input type="text" v-fbind:value="n">
</div>
<script type="text/javascript">
// 阻止 vue 在启动时生成生产提示
Vue.config.productionTip = false
// 自定义指令
// 1.函数式写法
Vue.directive("big",function(element,binding){
// 这里可以通过 element instanceof HTMLElement ,判断 element 是否是 HTMLElement 的实例对象
console.log(element instanceof HTMLElement) // true
console.log(binding)
element.innerText = binding.value * 10
})
// 2.对象式写法
Vue.directive("fbind",{
// bind(element,binding)回调函数,指令与元素成功绑定时调用
bind(element,binding){
console.log("bind")
element.value = binding.value
},
// inserted(element,binding)回调函数,指令所在元素被插入页面时调用
inserted(element,binding){
console.log("inserted")
element.focus()
},
// update(element,binding)回调函数,指令所在模板结构被重新解析时调用
update(element,binding){
console.log("update")
element.value = binding.value
}
})
new Vue({
el:"#root",
data(){
return{
n:1
}
}
})
</script>
</body>
</html>

浙公网安备 33010602011771号