vue自定義指令初探

指令.jpg

vue自定義指令初探

一、什么是自定義指令

自定義指令是用來(lái)操作DOM的。盡管Vue推崇數(shù)據(jù)驅(qū)動(dòng)視圖的理念,但并非所有情況都適合數(shù)據(jù)驅(qū)動(dòng)。自定義指令就是一種有效的補(bǔ)充和擴(kuò)展,不僅可用于定義任何的DOM操作,并且是可復(fù)用的。

在vue中,除了核心功能默認(rèn)內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊(cè)自定義指令。有的情況下,對(duì)普通 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令

二、自定義指令的核心知識(shí)

自定義指令分為鉤子函數(shù)和鉤子函數(shù)的參數(shù)

1、鉤子函數(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)下)。

我們會(huì)在稍后討論渲染函數(shù)時(shí)介紹更多 VNodes 的細(xì)節(jié)。

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

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

接下來(lái)我們來(lái)看一下鉤子函數(shù)的參數(shù) (即 el、binding、vnode 和 oldVnode)。

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

指令鉤子函數(shù)會(huì)被傳入以下參數(shù):

el:指令所綁定的元素,可以用來(lái)直接操作 DOM。 binding:一個(gè)對(duì)象,包含以下 property: name:指令名,不包括 v- 前綴。 value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。 oldValue:指令綁定的前一個(gè)值,僅在 update 和 componentUpdated 鉤子中可用。無(wú)論值是否改變都可用。 expression:字符串形式的指令表達(dá)式。例如 v-my-directive="1 + 1" 中,表達(dá)式為 "1 + 1"。 arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 "foo"。 modifiers:一個(gè)包含修飾符的對(duì)象。例如:v-my-directive.foo.bar 中,修飾符對(duì)象為 { foo: true, bar: true }。 vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)。移步 VNode API 來(lái)了解更多詳情。 oldVnode:上一個(gè)虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用。

三、動(dòng)態(tài)指令參數(shù)

指令的參數(shù)可以是動(dòng)態(tài)的。例如,在 v-mydirective:[argument]="value" 中,argument 參數(shù)可以根據(jù)組件實(shí)例數(shù)據(jù)進(jìn)行更新!這使得自定義指令可以在應(yīng)用中被靈活使用。

例如你想要?jiǎng)?chuàng)建一個(gè)自定義指令,用來(lái)通過(guò)固定布局將元素固定在頁(yè)面上。我們可以像這樣創(chuàng)建一個(gè)通過(guò)指令值來(lái)更新豎直位置像素值的自定義指令:

  <div id="baseexample">
  <p>Scroll down the page</p>
  <p v-pin="200">Stick me 200px from the top of the page</p>
</div>
Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    el.style.top = binding.value + 'px'
  }
})

new Vue({
  el: '#baseexample'
})
 // 這會(huì)把該元素固定在距離頁(yè)面頂部 200 像素的位置。但如果場(chǎng)景是我們需要把元素固定在左側(cè)而不是頂部又該怎么辦呢?這時(shí)使用動(dòng)態(tài)參數(shù)就可以非常方便地根據(jù)每個(gè)組件實(shí)例來(lái)進(jìn)行更新。

四 、vue bind和inserted的詳細(xì)區(qū)別

  1. 適用

需要對(duì)普通 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令

1.鉤子函數(shù)參數(shù)

除了 el 之外,其它參數(shù)都應(yīng)該是只讀的,切勿進(jìn)行修改

2.動(dòng)態(tài)指令參數(shù)

v-mydirective:[argument]=“value”

argument可以是動(dòng)態(tài)變化的,并且在鉤子里面實(shí)時(shí)更新的 4.鉤子區(qū)別

update 和 componentUpdated

共同點(diǎn):組件更新都會(huì)調(diào)用,update在componentUpdated之前

不同點(diǎn):
update 組件更新前的狀態(tài)
componentUpdated 組件更新后的狀態(tài)

場(chǎng)景:點(diǎn)擊事件,div的內(nèi)容追加 ??;

  update(el, binding,vnode,oldVnode){
    console.log(el.innerHTML);       // <div>!</div>
}

componentUpdated(el, binding,vnode,oldVnode){
    console.log(el.innerHTML);       // //<div>?。?lt;/div>
}

// 注意: 區(qū)別是div里面的!數(shù)量

bind 和 inserted

共同點(diǎn): dom插入都會(huì)調(diào)用,bind在inserted之前

不同點(diǎn):
    bind 時(shí)父節(jié)點(diǎn)為 null
    inserted 時(shí)父節(jié)點(diǎn)存在。
    bind是在dom樹(shù)繪制前調(diào)用,inserted在dom樹(shù)繪制后調(diào)用

bind: function (el) {
    console.log(el.parentNode)  // null
    console.log('bind')
},
inserted: function (el) {
    console.log(el.parentNode)  // <div class="directive-box">...</div>
    console.log('inserted')
}

五 、演示代碼

// 根據(jù)條見(jiàn)判斷 元素的顯示與隱藏
Vue.directive('changeColor', {
  
  inserted:function(el, binding) {
    el.style.color = 'red'
    el.style.background = '#ccc'
    // arg 獲取自定義指令的動(dòng)態(tài)參數(shù)
    console.log("binding1",binding.arg)
    if(binding.value < 3) {
      el.style.display="none"
    }else{
      el.style.display="block"
    }
  },
  update:function(el, binding,vnode,oldVnode){
    console.log("vnode",vnode,oldVnode)
    el.style.color = 'red'
    el.style.background = '#ccc'
    console.log("binding11",binding)
    if(binding.value < 3) {
      el.style.display="none"
    }else{
      el.style.display="block"
    }
    // 這個(gè)自定義指令會(huì)影響所有的使用數(shù)據(jù)
  }
})

代碼僅供參考,代碼不全

// 在很多時(shí)候,你可能想在 bind 和 update 時(shí)觸發(fā)相同行為,而不關(guān)心其它的鉤子。比如這樣寫(xiě):
  Vue.directive('changeColor',
    function(el, binding) {
      el.style.color = 'red'
      el.style.background = '#ccc'
      // arg 獲取自定義指令的動(dòng)態(tài)參數(shù)
      console.log("binding1111111",binding.arg)
      if(binding.value < 3) {
        el.style.display="none"
      }else{
        el.style.display="block"
      }
      // 這個(gè)自定義指令會(huì)影響所有的使用數(shù)據(jù)
  })

參考文章:https://blog.csdn.net/haduwi/article/details/104949560 vue bind和inserted的詳細(xì)區(qū)別

https://blog.csdn.net/qq_40299179/article/details/80086227

https://cn.vuejs.org/v2/cookbook/creating-custom-scroll-directives.html#%E7%9C%9F%E5%AE%9E%E7%9A%84%E7%A4%BA%E4%BE%8B%EF%BC%9A%E4%B8%BA%E7%BA%A7%E8%81%94%E5%8A%A8%E7%94%BB%E4%BD%BF%E7%94%A8%E4%B8%80%E4%B8%AA%E8%87%AA%E5%AE%9A%E4%B9%89%E6%BB%9A%E5%8A%A8%E6%8C%87%E4%BB%A4

https://cn.vuejs.org/v2/guide/custom-directive.html

掃碼_搜索聯(lián)合傳播樣式-標(biāo)準(zhǔn)色版_看圖王.png
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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