1.Vue自定義指令
除了核心功能默認(rèn)內(nèi)置的指令 (
v-model
和v-show
等)征绎,Vue允許我們注冊自定義指令用于元素上舔哪。當(dāng)我們需要對普通 DOM 元素進(jìn)行底層操作時(shí)稚铣,就可以用到用到自定義指令议纯。
2. 鉤子函數(shù):
配置對象中包含一下幾個(gè)鉤子函數(shù)(均為可選值):
鉤子函數(shù) 描述
- bind: 只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用存谎。在這里可以進(jìn)行一次性的初始化設(shè)置银萍。
- inserted(常用): 被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (僅保證父節(jié)點(diǎn)存在变勇,但不一定已被插入文檔中)。
- update: 所在組件的 VNode 更新時(shí)調(diào)用贴唇,但是可能發(fā)生在其子 VNode 更新之前搀绣。指令的值可能發(fā)生了改變,也可能沒有滤蝠。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見下)豌熄。
- componentUpdated: 指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
- unbind: 只調(diào)用一次物咳,指令與元素解綁時(shí)調(diào)用锣险。
3. 鉤子函數(shù)參數(shù):
指令鉤子函數(shù)會(huì)被傳入以下參數(shù):
el:指令所綁定的元素,可以用來直接操作 DOM览闰。
-
binding:一個(gè)對象芯肤,包含以下 property:
name:指令名,不包括 v- 前綴压鉴。
value:指令的綁定值崖咨,例如:v-my-directive="1 + 1" 中,綁定值為 2油吭。
oldValue:指令綁定的前一個(gè)值击蹲,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用婉宰。
-
expression:字符串形式的指令表達(dá)式歌豺。例如 v-my-
directive="1 + 1" 中,表達(dá)式為 "1 + 1"心包。
arg:傳給指令的參數(shù)类咧,可選。例如 v-my-directive:foo 中蟹腾,參數(shù)為 "foo"痕惋。
modifiers:一個(gè)包含修飾符的對象。例如:v-my-directive.foo.bar 中娃殖,修飾符對象為 { foo: true, bar: true }值戳。
vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)(這個(gè)參數(shù)本人沒有用過,有用過的大佬請指點(diǎn)一下)
oldVnode:上一個(gè)虛擬節(jié)點(diǎn)炉爆,僅在 update 和componentUpdated 鉤子中可用述寡。
4.全局注冊
全局注冊自定義指令是將我們的自定義指令掛載到vue實(shí)例上的柿隙,在項(xiàng)目中都可以使用。
- 全局指令注冊方法為:Vue.directive(dName, options) 傳入兩個(gè)參數(shù)
- 分別是
指令名
和配置對象
- 創(chuàng)建完之后鲫凶,我們就可以使用 v-指令名 的方式加在元素上,以使自定義指令生效
4.1使 input 進(jìn)入獲取焦點(diǎn)
import Vue from 'vue'
// 注冊一個(gè)全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當(dāng)被綁定的元素插入到 DOM 中時(shí)……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
- 使用
<input v-focus />
5.局部注冊
用法與 全局 注冊是一樣的衩辟, 只是寫法稍有不同
進(jìn)行局部注冊時(shí)螟炫, 我們的組件中可以接收一個(gè)directives選項(xiàng),
其中艺晴,鍵為指令名 值為配置對象
- 注冊
export default{
data(){
return { ... }
},
directives:{
focus:{
inserted: function (el) {
//element-ui中 el-input外層是div, 里面包裹的才是input, 因此用在 el-input上的話昼钻,要讓el-input里的子元素聚焦
//增加判斷可以使我們的v-focus通用性更強(qiáng)
el.tagName == 'INPUT' ? el.focus() : el.children[0].focus
}
}
}
}
- 使用
<input v-focus></input>
6.項(xiàng)目用到的自定義指令
6.1 防抖函數(shù):
點(diǎn)擊按鈕過快可能多次請求接口,用自定義指令做全局的函數(shù)防抖
- 在main.js中 全局注冊一個(gè)自定義指令:
/**防抖函數(shù)
* @el :指令所綁定的元素封寞,可以用來直接操作 DOM然评。
* @binding :綁定的事件或者值
*/
Vue.directive('debounce', {
inserted(el, binding) {
let timer = null
el.addEventListener('click', () => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
binding.value();
timer = null;
}, 500)
})
}
})
- 使用
<button v-debounce="send">發(fā)送</button>
6.2節(jié)流函數(shù)
觸發(fā)高頻事件后,n秒內(nèi)函數(shù)函數(shù)只會(huì)執(zhí)行一次狈究。
應(yīng)用場景: search搜索聯(lián)想碗淌,用戶在不斷輸入值時(shí)
- 在main.js中 全局注冊一個(gè)自定義指令
/**節(jié)流函數(shù)
* @el :指令所綁定的元素,可以用來直接操作 DOM抖锥。
* @binding :綁定的事件或者值
*/
Vue.directive('throttle', {
inserted(el, binding) {
let timer = null
el.addEventListener('change', () => {
if (!timer) {
timer = setTimeout(() => {
clearTimeout(timer)
binding.value();
timer = null;
}, 100)
}
})
}
})
- 使用
<input v-throttle="changeSearch" />