Vue自定义指令
介绍
Vue中的指令形如v-*
,如v-if,v-show,v-model等。同时,除了Vue自带的一些默认指令外,Vue同时运行用户自定义指令,来扩展指令功能。
使用场景
究竟什么情况下使用组件?而什么情况下使用指令呢?官方对此,给出了以下建议:
注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
也就是说,当你关注问题的抽象层级在DOM元素的时候,你就应该考虑使用自定义指令来完成需求了。
作用范围
自定义指令有两种作用范围,一种是申明在全局,全局内有效。另一种,则是局部指令。
钩子函数及相关参数见官网文档。
举个例子
需求
我需要设计一个自定义指令v-bug
,该指令可将作用元素的所有内容都替换为烫烫烫烫
,指令可以指定有几个烫,以及是否追加锟斤拷
。
1. 先将内容替换为一个烫
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
Vue.directive('bug', {
inserted: function (el) {
el.innerHTML = "烫"
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<HelloWorld v-bug />
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
效果展示
2. 生成指定个数的烫
main.js
...
Vue.directive('bug', {
inserted: function (el, binding) {
el.innerHTML = Array(binding.value).fill("烫").join("")
}
})
...
App.vue
<template>
<div id="app">
<HelloWorld v-bug="12" />
</div>
</template>
3. 指定是否追加锟斤拷
main.js
...
Vue.directive('bug', {
inserted: function (el, binding) {
let html = Array(binding.value).fill("烫").join("")
if(binding.modifiers.suffix){
html += "锟斤拷"
}
el.innerHTML = html
}
})
...
App.vue
<template>
<div id="app">
<HelloWorld v-bug.suffix="12" />
</div>
</template>
但是此时的代码有个非常严重的问题,从上文代码中可看出,内容的改变只在inserted的时候执行。如果我们将指令后面设置为变量,变量值的改变却不会影响到烫
个数(这一点都不Vue),所有我们应再监听一下指令的updated钩子函数。
4. 数据驱动(动态改变)
App.vue
<script>
import HelloWorld from "./components/HelloWorld.vue";
let interval = null
export default {
name: "App",
components: {
HelloWorld
},
data() {
return {
num: 12
};
},
created() {
interval = setInterval(() => {
this.num++;
}, 1000);
},
beforeDestroy(){
clearInterval(interval)
}
};
</script>
main.js
...
function generateHtml(binding){
let html = Array(binding.value).fill("烫").join("")
if (binding.modifiers.suffix) {
html += "锟斤拷"
}
return html
}
Vue.directive('bug', {
inserted: function (el, binding) {
el.innerHTML = generateHtml(binding)
},
update: function (el, binding) {
if (binding.oldValue !== binding.value) {
el.innerHTML = generateHtml(binding)
}
},
})
...
需求完成!
版权声明: (https://www.thinkmoon.cn/post/910)
本文首发于指尖魔法屋-Vue自定义指令
转载或引用必须申明原指尖魔法屋来源及源地址!