16.自定义指令
2022/4/22 6:12:51
本文主要是介绍16.自定义指令,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
函数式
通过一个例子来讲解函数式自定义指令
按按钮n加1,同时显示放大十倍后的n。
<body> <div id="root"> <h2>我是:<span v-text="n"></span></h2> <h2 >我是十倍的:<span v-big="n"></span></h2> <button @click="n++">点我+1</button> </div> </body> <script> Vue.config.productionTip = false new Vue({ el:"#root", data:{ n:1 }, directives:{ big(element,binding){ element.innerText = binding.value * 10 } } }) </script>
通过在directives中创建函数来实现函数式自定义指令,传入的参数第一个是当前的节点,第二个是绑定的值。
在两种地方这里的指令中的函数会被调用
-
指令与元素成功绑定时(一上来)。
-
指令所在的模板被重新解析时。
对象式
对象式的自定义指令是对函数式的一种补充,因为函数式有缺陷。
需求:
每次点击按钮,input输入框中的数据为n的十倍,同时获取焦点
<body> <div id="root"> <h2>{{n}}</h2> <button @click="n++">点我+1</button> <input type="text" v-fbind="n"> </div> </body> <script> Vue.config.productionTip = false new Vue({ el:"#root", data:{ n:1 }, directives:{ fbind(element,binding) { element.value = binding.value element.focus() } } }) </script>
每次点击都会显示n的十倍,但是初始的焦点不在输入框中。
从原始的js来解释这个问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .demo{ background-color: orange; } </style> </head> <body> <button id="btn">点我创建输入框</button> <script> const btn = document.getElementById('btn') btn.onclick = () => { const input = document.createElement("input") input.className = "demo" input.value = 100 console.log(input.parentElement) document.body.appendChild(input) // 放入父节点之后才能生效 input.focus() console.log(input.parentElement) } </script> </body> </html>
可以从代码中看到,有些操作放在父节点之后才能生效,例如获取焦点、改变父节点属性等需要对父节点DOM的操作需要在子节点放入父节点之后操作。
而我们的函数式自定义指令只有在绑定和重新解析的时候执行,在第一次绑定的时候,节点还没有放入DOM中,因此第一次焦点不在输入框。
而对象式可以解决这类问题
<body> <div id="root"> <h2>{{n}}</h2> <button @click="n++">点我+1</button> <input type="text" v-fbind="n"> </div> </body> <script> Vue.config.productionTip = false new Vue({ el:"#root", data:{ n:1 }, directives:{ fbind:{ bind(element,binding){ console.log("bind") element.value = binding.value * 10 }, inserted(element,binding){ console.log("inserted") element.focus() }, update(element,binding){ console.log("update") element.value = binding.value * 10 element.focus() } } } }) </script>
对象式有三个函数分别是bind、inserted、update。
- bind是对数据和节点进行绑定的时候调用
- inserted是将节点插入父节点时调用
- update模型更新的时候调用
因此通过在inserted之后获取焦点可以实现第一次进入获取焦点。
函数式相当于简化的对象式,函数式中的函数其实代表了bind和update。
注意事项
全局自定义指令
上面讲的都是局部自定义指令,可以写成全局自定义指令
<script> VUE.directive('fbind',{ bind(element,binding){ console.log("bind") element.value = binding.value * 10 }, inserted(element,binding){ console.log("inserted") element.focus() }, update(element,binding){ console.log("update") element.value = binding.value * 10 element.focus() } }) VUE.directive('fbind2',function(element, binding){ element.value = binding.value * 10 element.focus() }) </script>
大小写问题
不能写成bigName这种形式,因为VUE指令无法识别大小写
<body> <div id="root"> <h2>我是:<span v-text="n"></span></h2> <h2 >我是十倍的:<span v-bigNumber="n"></span></h2> <button @click="n++">点我+1</button> </div> </body> <script> Vue.config.productionTip = false new Vue({ el:"#root", data:{ n:1 }, directives:{ bigNumber(element,binding){ element.innerText = binding.value * 10 } } }) </script>
这样写会报错
可以统一改成小写但是不符合命名规范,因此采用kebab-case命名方式,也就是用-来分割单词big-number,而不能采用驼峰命名法,如果采用big-number命名,不能用简写形式,必须要在指令名上加引号。
'bigNumber':function(element,binding){ element.innerText = binding.value * 10 } 'fbind':{ bind(element,binding){ element.value = binding.value * 10 element.focus() }, inserted(element,binding){ }, update(element,binding){ element.value = binding.value * 10 element.focus() } }
总结
语法
-
局部指令
//对象式 new Vue({ directives:{指令名:配置对象} }) // 函数式 new Vue({ directives{指令名:回调函数} })
-
全局指令
- Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
对象式三个回调
- bind是对数据和节点进行绑定的时候调用
- inserted是将节点插入父节点时调用
- update模型更新的时候调用
注意事项
- 指令定义时不加v-,但使用时要加v-
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名,并且需要用引号包裹
这篇关于16.自定义指令的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2025-01-04百万架构师第六课:设计模式:策略模式及模板模式
- 2025-01-04百万架构师第七课:设计模式:装饰器模式及观察者模式
- 2025-01-04适用于企业管理的协作工具API推荐
- 2025-01-04挑战16:被限流的CPU
- 2025-01-03企业在选择工具时,如何评估其背后的技术团队
- 2025-01-03Angular中打造动态多彩标签组件的方法
- 2025-01-03Flask过时了吗?FastAPI才是未来?
- 2025-01-0311个每位开发者都应知道的免费实用网站
- 2025-01-03从REST到GraphQL:为什么以及我是如何完成转型的
- 2025-01-03掌握RAG:从单次问答到连续对话