Vue學習之旅Part5:Vue全局指令和私有指令的自定義及使用

一、自定義全局指令

開門見山 舉個栗子:

<label>
    搜索
    <input type="text" id="search">
</label>

此時 若要觸發這個輸入框的獲得焦點事件 在原生方法中是這樣的:

document.getElementById("search").focus();

而在Vue中 使用自定義指令來實現該效果
指令 就是形如v-model v-text之類的 只不過這些是Vue默認提供的
而自定義指令 就是自定義的(廢話

在Vue中 所有的指令使用的時候都以v-開頭

自定義一個名爲v-focus的自定義指令:
加在標籤中

<label>
    搜索
    <input type="text" id="search" v-focus>
</label>

然後 用Vue.directive()來定義全局指令
語法:Vue.directive(指令名稱,對象)
第一個參數是指令的名稱 在定義的時候 指令前面無需加上v-的前綴 但在調用的時候必須加
第二個參數是個對象 該對象上面有一些指令相關的鉤子函數 這些函數可以在特定階段執行相關的操作

在每個鉤子函數中 第一個參數永遠是el 其表示被綁定了該指令的元素(element)【當然 參數名可隨意取】
它是原生的js的dom對象 因此可以在其上面盡情使用js方法

常用的鉤子函數有bind inserted和updated:

  • bind是每當指令綁定到元素上時 會立即執行該bind函數
    只會執行一次 因爲一個指令只能綁定到一個元素上一次
  • inserted是當元素插入到DOM中的時候會執行該inserted函數
    其也只會執行一次
  • updated是當DOM節點(VNode組件)更新的時候 會執行該upload函數
    可能會觸發多次
Vue.directive("focus",{
            // 鉤子函數
            
            // 在bind剛綁定的時候 元素還並沒有被放到dom中去 因此此時調用focus()方法沒作用 不會生效 因爲一個元素只有在插入dom之後才能獲取焦點
            bind:function(el)
            {
                // el.focus();
            },
            
            // 元素插入到DOM中的時候會執行該inserted函數
            // 【只會執行一次】
            inserted:function(el)
            {
                el.focus();
            },
            
            // 當DOM節點(VNode組件)更新的時候 會執行該upload函數
            // 【可能會觸發多次】
            updated:function(el)
            {
            
            }
        })

除此之外 還有:

  • componentUpdated:指令所在組件的DOM節點(VNode組件)及其子DOM節點(VNode組件)全部更新後調用
  • unbind:指令與元素解綁時調用
    只調用一次

如此 即可實現自定義指令了


當然 樣式和行爲還是有區別的:
何爲樣式?樣式就是比如設置顏色之類的
而行爲 就是比如focus()之類的js行爲

拿自定義字體顏色指令舉個栗子吧:

Vue.directive("color",{
            bind:function(el)
            {
                el.style.color="aqua";
            }
        })

我們發現樣式是可以在bind裏設置的
那是因爲因爲只要樣式被解析了 那麼顯示在頁面上就會帶有顏色
樣式只要通過指令綁定給了元素 不管這個元素有沒有被插入到頁面中去 這個元素肯定會有了一個內聯樣式
在那之後 元素肯定會顯示到頁面中 在這個時候 瀏覽器的渲染引擎必然會解析樣式 然後應用給該元素

但 focus()之類的方法是一個行爲 行爲必須添加到DOM中才能獲得焦點 在bind的時候還只是在內存中 並沒有添加到DOM上
在內存中調用的行爲 然後再渲染到頁面上時 自然是無效的
而insert是到了頁面上之後才調用 因此行爲會有效

總而言之 和js行爲有關的操作最好在inserted裏執行 防止js行爲不生效
而 和樣式相關的操作 通常可以放在bind中執行


在自定義指令中拿到傳遞的值

在定義的時候 要加上引號 因爲傳遞的是一個字符串
若不加引號 則會識別爲是一個變量

<input type="text" id="search" v-color="'blue'">

首先 看一下鉤子函數共有哪些參數:

  • el:指令所綁定的元素 可用來直接操作DOM
  • binding:一個對象 包含以下屬性:
    name:指令名(不包括v-前綴)
    value:指令的綁定值
    例:在v-my-directive=“1+1"中 綁定值是爲2 即:value是經過字符串解析後的結果
    oldValue:指令綁定的前一個值
    僅在update和componentUpdated鉤子中可用
    無論值是否改變都可用
    expression:字符串形式的指令表達式
    例:在v-my-directive=“1+1"中 表達式爲"1+1” 即:expression是不經過字符串解析後的結果 原原本本的結果
    arg:傳給指令的參數
    例:在v-my-directive:foo中 參數爲"foo”
    modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象爲 { foo: true, bar: true }
  • vnode:Vue 編譯生成的虛擬節點
  • oldVnode:上一個虛擬節點
    僅在update和componentUpdated鉤子中可用

在這裏插入圖片描述
拿到傳遞的值
例:

// 自定義設置字體顏色指令
Vue.directive("color",{
    bind:function(el,binding) // 此處的el和binding可任意命名
    {
        console.log(binding.value);
        el.style.color=binding.value;
    }
})

二、自定義私有指令

就像過濾器一樣 指令也是不但有共有的指令 也有私有的指令
自定義私有指令其實和自定義私有過濾器類似
都是在Vue實例中的屬性對象裏進行設置

<div id="app2">
	<h3 v-fontWeight="1000">{{date | dateFormat}}</h3>
</div>
<script>
	var vm2=new Vue({
	            el:'#app2',
	            data:{
	                date:new Date()
	            },
	            methods:{},
	            filters:{},
	            // 自定義私有指令
	            directives:{
	                "fontweight":{
	                    bind:function(el,binding)
	                    {
	                        el.style.fontWeight=binding.value;
	                    }
	                }
	            }
	        })
</script>

三、指令的簡寫

Vue的自定義指令還支持簡寫

如果想在bindupdate這兩個鉤子上進行重複的動作
且不關心其它的鉤子函數

那麼 可以直接在指令名後面跟上方法

例:

<div id="app2">
	<h3 v-fontWeight="1000" v-fontsize="'50'">{{date | dateFormat}}</h3>
</div>
<script>
	var vm2=new Vue({
	            el:'#app2',
	            data:{
	                date:new Date()
	            },
	            methods:{},
	            filters:{},
	            // 自定義私有指令
	            directives:{
	                // 字體粗細
	                "fontweight":{
	                    bind:function(el,binding)
	                    {
	                        el.style.fontWeight=binding.value;
	                    }
	                },
	                // 字體大小
	                "fontsize":function(el,binding) // 該function就相當於將裏面的代碼寫到【且只寫到】bind和update鉤子上去了
	                {
	                    el.style.fontSize=parseInt(binding.value)+"px";
	                }
	            }
	        })
</script>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章