除了核心功能默認內置的指令,Vue也允許注冊自定義指令
頁面加載后,讓文本框自動獲取焦點,原生js做法是獲取文本框元素后調用focus()方法,但Vue不建議手動操作DOM元素,所以此時要自定義指令
這里需要注意的是v-on指令綁定focus事件的方式是實現不了上面需求的,區別就像onfocus和focus(),前者是事件綁定,當元素獲得焦點時去執行事件處理函數,而后者是方法,調用后會讓元素獲得焦點,onclick和click()同理
自定義全局指令
Vue.directive( ' 自定義指令名 ' , { } )
參數一是指令的名字,注意定義的時候指令前不需要加 v- 前綴,但調用的時候必須加上這個前綴
參數二是一個對象,在這對象身上有一些指令相關的函數,這些函數可以在特定階段執行相關的操作,叫鈎子函數
<body>
<div id="app">
<input type="text" id="text" v-focus><!--自定義全局指令后可在標簽內直接使用這個指令-->
</div>
<script>
//注冊一個全局自定義指令
Vue.directive('focus', { //每當指令綁定到元素上時,會立即執行這個bind函數,只執行一次
bind: function () { }, //inserted表示元素插入到DOM中時,會執行inserted函數,只觸發一次,el表示被綁定的那個原生js對象
inserted: function (el) { el.focus() }, //當VNode更新時會執行updated,可能觸發多次
updated:function(){ } }) var vm = new Vue({ el: '#app', data: { } }) </script>
</body>
鈎子函數我覺得跟原生事件注冊方式相似 dom.onclick = function(){ } ,就是有些狀態會被Vue捕捉並貼上名字(如bind這個名字代表指令綁定到了元素上),名字是為了讓我們可以將自定義處理函數“鈎”在上面,這樣,我們就可以決定哪種狀態做哪種事
在這個案例中,el.focus()不可放在bind函數里,因為指令雖然綁定到了元素上,但元素還沒有插入到DOM中也就是元素還在內存中沒有被渲染到頁面上,這時在內存調用focus方法沒有作用,而inserted則表示元素已經加載到網頁上了,此時使用focus才是有效的
自定義全局指令,指定文本框文字顏色
Vue.directive('color', { bind: function (el) { //鈎子函數的第一個參數都是被綁定的DOM元素
el.style.color = 'red' } })
因為是樣式,所以不需要元素插入到DOM中,就好像link引入CSS文件時並不關心元素是否加載
和js行為有關的操作,最好在inserted中執行,和樣式相關的操作都可在bind中執行
鈎子函數第一個參數是被綁定的原生DOM元素,第二個元素是一個binding對象,該對象有三個重要的屬性name、value和expression
<div id="app">
<!--#ff4200如果不用單引號引上的話會被當作data里的變量,數字則無影響-->
<input type="text" id="text" v-color="'#ff4200'">
</div>
Vue.directive('color', {
bind: function (el,binding) { //形參名字可隨意,但一般是這么寫
console.log(binding.name) //color
console.log(binding.value) //#ff4200
}
})
自定義私有指令
自定義私有指令跟自定義過濾器的套路是一樣的,在構造函數里定義
var vm = new Vue({ el: '#app', directives: { 'color': { //指令名要加上引號 bind: function (el, binding) { el.style.color = binding.value } } } })
函數簡寫
也就是如果只用到bind或update,就可省略指令定義對象的書寫