Vue指令和Vue組件之間的關(guān)系
很多時(shí)候,對(duì)于初學(xué)者來(lái)說(shuō),看完指令的使用會(huì)發(fā)現(xiàn)組件的使用和指令的自定義有幾分相似之處。其實(shí),并非如此,組件和指令完全不是一個(gè)層級(jí)上的概念。打個(gè)比方:組件是一個(gè)房子,它可以嵌套使用,房子里邊又有窗戶,門,桌子,床,柜子等這些子組件。而指令是附著在組件上的某種行為或者功能,門和窗戶可以打開關(guān)閉,桌子可以折疊,柜子可以打開關(guān)上等等。以下是對(duì)于組件和指令的定義,希望能夠讓大家更清晰的理解:
組件:一般是指一個(gè)獨(dú)立實(shí)體,組件之間的關(guān)系通常都是樹狀。
Vue指令:用以改寫某個(gè)組件的默認(rèn)行為,或者增強(qiáng)使其獲得額外功能,一般來(lái)說(shuō)可以在同一個(gè)組件上疊加若干個(gè)指令,使其獲得多種功能。比如 v-if,它可以安裝或者卸載組件。
Vue 指令生命周期
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ā)生了改變,也可能沒(méi)有。但是你可以通過(guò)比較更新前后的值來(lái)忽略不必要的模板更新 。
componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。
生命周期函數(shù)中的參數(shù)
el: 指令所綁定的元素,可以用來(lái)直接操作 DOM,就是放置指令的那個(gè)元素。
binding: 一個(gè)對(duì)象,里面包含了幾個(gè)屬性,這里不多展開說(shuō)明,官方文檔上都有很詳細(xì)的描述。
vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)。
oldVnode:上一個(gè)虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用
實(shí)例
1.用來(lái)操作DOM
Vue.directive('img',{
//DOM
inserted:function(el,binding){
var color =Math.floor(Math.random()*1000000);
el.style.backgroundColor = '#' + color;
var img = new Image();
img.src = binding.value;
img.onload = function(){
el.style.backgroundImage = 'url(' + binding.value + ')';
}
}
})
<div v-img="val.url" v-for="val in list"></div>
//此處圖片路徑為示意結(jié)果,為了能夠更好的看出本段測(cè)試代碼的效果,建議大家選擇網(wǎng)上比較高清的圖片
list:[
{url:'1.jpg'},
{url:'1.jpg'},
{url:'1.jpg'}
]
2.用于集成第三方插件
var hljs = require('highlight.js');
Vue.directive('highlight',function(el){
hljs.hightlightBlock(el);
})
<pre>
<code v-hightlight><alert-menu
:menudata="menu"
:e="eventObj"
ref="menu"
v-on:menuEvent="handle">
</alert-menu>
</code>
</pre>
3.擴(kuò)展第三方組件指令 比如<mt-input></mt-input> 等,此時(shí)用局部指令表述
directives: {
'mtfocus' (el, binding, vnode) {
let mtinput = el.querySelector('input')
mtinput.onfocus = function () {
...//如果要對(duì)節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行更改,且更改要映射到頁(yè)面上,則更改可在vnode.context上進(jìn)行,這樣,改完之后,改變就會(huì)映射到頁(yè)面
}
mtinput.onblur = function () {
...//同上理
}
}
}