除了默認(rèn)設(shè)置的核心指令( v-model 和 v-show ),Vue 也允許注冊(cè)自定義指令谊路。注意赊锚,在 Vue2.0 里面成箫,代碼復(fù)用的主要形式和抽象是組件——然而格郁,有的情況下,你仍然需要對(duì)純 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令腹殿。
官方建議directive是對(duì)純 DOM 元素進(jìn)行底層操作使用独悴,一般情況下還是建議使用組件的復(fù)用。
directive的意義
自定義指令是用來(lái)操作DOM的锣尉。
盡管數(shù)據(jù)驅(qū)動(dòng)是Vue的核心之一刻炒,但是在實(shí)際情況下,并不是所有的情況都可以用數(shù)據(jù)來(lái)驅(qū)動(dòng)視圖自沧,我們不可避免的會(huì)在有些情況下有操作DOM的需求坟奥,所以directive也就出現(xiàn)了。自定義指令就是一種有效的補(bǔ)充和擴(kuò)展拇厢,不僅可用于定義任何的DOM操作爱谁,并且是可復(fù)用的。
官方栗子
code
// 注冊(cè)一個(gè)全局自定義指令 v-focus
Vue.directive('focus', {
// 當(dāng)綁定元素插入到 DOM 中孝偎。
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
//局部指令
directive: {
focus(el){
el.focus()
}
}
use
<input v-focus>
//input標(biāo)簽自動(dòng)獲得標(biāo)簽
是不是感覺很簡(jiǎn)單管行?相信自己,其實(shí)vue大法真心不難邪媳,難得是如何應(yīng)用捐顷。下面先來(lái)簡(jiǎn)單看看的鉤子函數(shù)。
鉤子函數(shù)
- bind:在該元素綁定指令時(shí)調(diào)用且僅調(diào)用一次雨效,用于初始化
- inserted:元素插入父節(jié)點(diǎn)時(shí)調(diào)用(可能仍在虛擬Dom中)
- update:模板更新時(shí)調(diào)用
- componentUpdated: 被綁定元素所在模板完成一次更新周期時(shí)調(diào)用迅涮。
- unbind: 只調(diào)用一次, 指令與元素解綁時(shí)調(diào)用徽龟。
鉤子參數(shù)
- el: 指令所綁定的元素叮姑,可以用來(lái)直接操作 DOM 。
- binding: 一個(gè)對(duì)象据悔,包含以下屬性:
- name: 指令名传透,不包括 v- 前綴。
- value: 指令的綁定值
- oldValue: 指令綁定的前一個(gè)值极颓,僅在 update 和 componentUpdated 鉤子中可用朱盐。無(wú)論值是否改變都可用。
- expression: 綁定值的字符串形式菠隆。 例如 v-my-directive="1 + 1" 兵琳, expression 的值是 "1 + 1"。
- arg: 傳給指令的參數(shù)骇径。例如 v-my-directive:foo躯肌, arg 的值是 "foo"。
- modifiers: 一個(gè)包含修飾符的對(duì)象破衔。 例如: v-my-directive.foo.bar, 修飾符對(duì)象 modifiers 的值是 { foo: true, bar: true }清女。
- vnode: Vue 編譯生成的虛擬節(jié)點(diǎn)。
- oldVnode: 上一個(gè)虛擬節(jié)點(diǎn)晰筛,僅在 update 和 componentUpdated 鉤子中可用嫡丙。
實(shí)際應(yīng)用
directive的語(yǔ)法就這么簡(jiǎn)單忠售,在合適的鉤子中做應(yīng)該做的事就可以了。下面會(huì)列出兩個(gè)使用指令的栗子
集成第三方插件
用了一段時(shí)間的vue迄沫,其實(shí)我都沒有留意directive具體使用稻扬,一般來(lái)言真的很少使用到。直到有一次需要集成第三方插件到Vue時(shí)才發(fā)現(xiàn)羊瘩,原來(lái)directive是集成第三方插件最合適也是最簡(jiǎn)單的方式泰佳。凡是關(guān)于第三方的集成,都可以嘗試使用directive
import Vue from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/monokai-sublime.css'
Vue.directive('highlight', {
bind(el){
hljs.highlightBlock(el);
},
})
use
<pre>
<code v-highlight>
//code here
</code>
</pre>
如上尘吗,我注冊(cè)了一個(gè)全局的指令 highlight逝她。 指令的作用就是高亮代碼,當(dāng)元素帶上'v-highlight'時(shí)睬捶,hljs就會(huì)去初始化該Dom黔宛。
當(dāng)然我這是可以使用組件來(lái)實(shí)現(xiàn)這個(gè)功能,但絕對(duì)沒有指令那么方便快捷擒贸,下面是一個(gè)簡(jiǎn)略的組件臀晃,可以看出,不僅定義和使用都比指令來(lái)的復(fù)雜介劫。
<template>
<pre>
<code ref="code">
<slot name="code"></slot>
</code>
</pre>
</template>
<script>
import hljs from 'highlight.js'
import 'highlight.js/styles/monokai-sublime.css'
export default {
mounted(){
hljs.highlightBlock(this.$refs.code);
}
}
</script>
指令驗(yàn)證
如果需要一個(gè)可以復(fù)用的驗(yàn)證徽惋,我們也可以使指令來(lái)完成,下面來(lái)看一個(gè)簡(jiǎn)單的栗子:
Vue.directive('checkName', {
//監(jiān)控?cái)?shù)據(jù)變化
update(el, binding){
let regex = /^[a-zA-z]{6,10}$/g;
//=value === oldValue, 避免重復(fù)更新
if(binding.value !== binding.oldValue){
el.style.border = regex.test(binding.value) ? '' : '1px solid red';
}
}
})
user
<input v-model='value1' v-checkName='value1'></input>
<input v-model='value2' v-checkName='value2'></input>
<input v-model='value3' v-checkName='value3'></input>
<input v-model='value4' v-checkName='value4'></input>
//當(dāng)value的值不是6-10的字母的時(shí)座韵,input的boder變?yōu)榧t色;
result
結(jié)果很明顯险绘,不符合規(guī)則的數(shù)據(jù),input的邊框變紅了誉碴。
End
這里只是抄寫下官方的文檔宦棺,舉兩個(gè)栗子,就是那么簡(jiǎn)單黔帕,任性 ( ̄~ ̄) 代咸!其實(shí)主要想說(shuō)明白的一件事就是明確dirctive的意義:指令是用來(lái)操作DOM的,希望能起到拋磚引玉的作用吧蹬屹。