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>