Vue2.0系列(七)自定義指令

在vue2.0中,代碼復(fù)用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對(duì)普通DOM元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令。

自定義指令最重要的兩個(gè)部分就是鉤子函數(shù)和鉤子函數(shù)對(duì)應(yīng)的參數(shù)。

鉤子函數(shù)

一個(gè)指令定義對(duì)象可以提供如下幾個(gè)鉤子函數(shù) (均為可選):

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)忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見(jiàn)下)。

componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。

unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。

鉤子函數(shù)的參數(shù)

便于理解的小案例

好了為了便于理解,我們先看一下在自定義指令中,我們能接收到的

<div id="app" v-demo="message"></div>

<script type="text/javascript" src='https://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/teamFrighting/js/vue.min.js'></script>
<script type="text/javascript">
Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})
new Vue({
  el: '#app',
  data: {
    message: 'hello!'
  }
})

頁(yè)面顯示:

從輸出的結(jié)果可以看出,在自定義指令中能接收到傳入的參數(shù)和元素等等

再理解一下自定義指令各個(gè)鉤子的區(qū)別

<div id="app" >
  <input type="text" v-demo="message">
</div>

<script type="text/javascript" src='https://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/teamFrighting/js/vue.min.js'></script>
<script type="text/javascript">
Vue.directive('demo', {
  bind: function (el, binding) {
    el.value=binding.value+'我是飯飯';
    console.log(el.value)
  },
  inserted:function (el, binding) {
    el.value=binding.value+'你叫什么名字?';
    console.log(el.value)
  },
  update:function (el, binding) {
    //暫時(shí)沒(méi)有很好的例子
    console.log(el.value)
  },
  componentUpdated:function (el, binding) {
     //暫時(shí)沒(méi)有很好的例子
    console.log(el.value)
  },
  unbind:function (el, binding) {
     //暫時(shí)沒(méi)有很好的例子  
    console.log(el.value)
  }
})
new Vue({
  el: '#app',
  data: {
    message: 'hello,'
  }
})

頁(yè)面顯示:


從頁(yè)面顯示可以看出bind: 一旦指令附加到元素時(shí)觸發(fā),inserted: 一旦元素被添加到父元素時(shí)觸發(fā)以及兩者的區(qū)別,這兩者也是我們開(kāi)發(fā)過(guò)程中常用的。

常見(jiàn)自定義指令:

1、在圖片未完成加載前,用隨機(jī)的背景色占位,圖片加載完成后才直接渲染出來(lái)。

<div id="app" >

  <div v-img='val.url'  v-for="val in list"></div>
  
</div>

<script type="text/javascript" src='https://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/teamFrighting/js/vue.min.js'></script>


<script type="text/javascript">
Vue.directive('img', {
  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 +')'
    }
  }
})
new Vue({
  el: '#app',
  data: {
    list:[
      {
        url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan04.jpg'
      },
      {
        url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan03.jpg'
      },
      {
        url:'http://i0.jrjimg.cn/zqt-red-1000/focus/focus2017YMZ/Billboard/img/tan04.jpg'
      }
    ]
  }
})

案例效果:


2、自定義指令的第二用處是用于集成第三方插件。
比如寫文檔通常會(huì)用到highlight.js,我們可以直接將其封裝為一個(gè)自定義指令,這樣highlight.js就變成了Vue的一個(gè)新功能

但凡遇到第三方插件如何與Vue.js集成的問(wèn)題,都可以嘗試用自定義指令實(shí)現(xiàn)

本文案例借鑒:https://www.cnblogs.com/kidney/p/6296304.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容