Vue可複用性&組合
二、自定義指令
除了核心功能預設內建的指令(v-model和v-show),Vue也允許註冊自定義指令。在Vue2.0中,程式碼複用和抽象的主要形式是元件,然而有的情況下,你仍然需要對普通DOM元素進行底層操作,這時會用到自定義指令。如當頁面載入時,輸入框將獲得焦點,只要你在開啟這個頁面後還沒點選過任何內容,這個輸入框就應當還是處於聚焦狀態。
// 如果不使用指令,就需要操作DOM元素,這是vue不提倡的
document.getElementById('search').focus();
指令的名稱:定義時,指令的名稱不需要加v-字首;呼叫時,必須加v-字首。
一個物件:包含指令相關的函式,這些函式在特定的階段執行相關的操作。
註冊一個全域性自定義指令。
Vue.directive('focus',{
// 當被繫結的元素插入到DOM中時
inserted:function(el){
// 聚焦元素,一個元素只有插入DOM之後,才能獲取焦點
el.focus()
}
})
註冊區域性指令,元件中接受一個directives的選項。
directives:{
focus:{
inserted:function(el){
el.focus()
}
}
}
然後可以在模板中任何元素上使用新的v-focus屬性。
<input v-focus>
1、鉤子函式
一個指令定義物件可以提供如下幾個鉤子函式(均為可選):
bind:只調用一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定,如用於繫結樣式,只要通過指令繫結給了元素,不管該元素有沒有被插入到頁面中去,肯定有了一個內聯的樣式。
inserted:只調用一次,被繫結元素插入父節點(DOM樹中)時呼叫(僅保證父節點存在,但不一定已被插入文件中)。可繫結和JS行為有關的操作,防止JS行為不生效。
update:可能呼叫多次,所在元件的VNode更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後的值來忽略不必要的模板更新。
componentUpdated:指令所在元件的VNode及其子VNode全部更新後呼叫。
unbind:只調用一次,指令與元素解綁時呼叫。
2、鉤子函式的引數
el:指令所繫結的元素,是一個原生JS物件,可直接操作DOM。
binding:一個物件,包含以下屬性:
name:指令名,不包括v-字首。
value:指令的繫結值,如v-my-directive="1+1"中,繫結值為2。
expression:繫結值的字串形式,如v-my-directive="1+1"中,表示式為1+1。
oldValue:指令繫結的前一個值,僅在update和componentUpdated鉤子中可用,無論值是否改變都可用。
arg:傳遞指令的引數,如v-my-directive:foo中,引數為foo。
modifiers:一個包含修飾符的物件,如v-my-directive:foo.bar中,修飾符物件為{foo:true,bar:true}。
vnode:Vue編譯生成的虛擬節點。
oldVnode:上一個虛擬節點,僅在update和componentUpdated鉤子中可用
除了el之外,其它引數都應該是隻讀的,切勿進行修改。如果需要在鉤子之間共享資料,建議通過元素的dataset來進行。
3、函式簡寫
自定義指令的簡寫形式,等同於定義了 bind 和 update 兩個鉤子函式,而不關心其它的鉤子。
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
五、過濾器
Vue.js允許自定義過濾器,可被用於一些常見的文字格式化。過濾器可以用在兩個地方:雙花括號插值和v-bind表示式(後者從 2.1.0+開始支援)。過濾器應該被新增在JavaScript表示式的尾部,由“管道”符號指示。過濾器呼叫時的格式:
<!-- 在雙花括號中 -->
{{ message | 過濾器的名稱 }}
<!-- 在`v-bind`中 -->
<div v-bind:id="rawId | formatId"></div>
過濾器的定義語法:
(1)在一個元件的選項中定義本地的過濾器
filters:{
過濾器名稱:function(data){
return data+'123';
}
}
(2)在建立Vue例項之前定義全域性過濾器,所有vm例項共享
Vue.filter('過濾器名稱',function(data){
return data+'123';
})
var vm=new Vue({
// ...
});
{{ message | filterA | filterB }} 過濾器可以串聯,過濾器函式總接收表示式的值 (之前的操作鏈的結果) 作為第一個引數。
{{ message | filterA('data', arg1, arg2) }} 過濾器可以有多個引數,第一個引數是過濾器管道符前面傳來的資料。
<body>
<div id="app">
<p>{{msg | filterA('無敵','可愛') | filterB}}</p>
</div>
<script>
Vue.filter('filterA',function(msg,arg1,arg2){
return msg.replace(/無情/g,arg1+arg2);
});
Vue.filter('filterB',function(msg){
return '===='+msg+'====';
})
var vm=new Vue({
el:'#app',
data:{
msg:'你無情,你殘酷! 那你就不無情,不殘酷!? 我哪裡無情,哪裡殘酷!?'
},
filters:{
filterA:function(msg,arg1,arg2){
return msg.replace(/殘酷/g,arg1+arg2);
}
}
});
</script>
</body>
當有區域性和全域性兩個名稱相同的過濾器時,以就近原則進行呼叫,即區域性過濾器優先於全域性過濾器。