Vue自定義指令 directive

  • 使用場(chǎng)景

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

  • 注冊(cè)方式以及用法

directive 分為全局注冊(cè)以及局部注冊(cè)兩種,注冊(cè)后在標(biāo)簽上使用 v- 注冊(cè)名 即可使用,在下例中,使用 v-name

// 全局注冊(cè)
Vue.directive('name',function(){
  // do something
});
// 局部注冊(cè)
new Vue({
  directives:{
    name:{
      // do something
    }
  }
});
  • 鉤子函數(shù)

    在注冊(cè) directive 時(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ā)生了改變,也可能沒有。但是你可以通過比較更新前后的值來(lái)忽略不必要的模板更新 。
    • componentUpdated : 指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。
    • unbind : 只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。

我們?cè)阢^子函數(shù)中可以獲取到以下參數(shù):

  • el :指令所綁定的元素,可以用來(lái)直接操作 DOM

  • binding :一個(gè)對(duì)象,包含以下 property:

    • name: 指令名,不包括 v- 前綴
    • value:指令的綁定值,例如:v-my-directive="1 + 1"中,綁定值為 2
    • oldValue:指令綁定的前一個(gè)值,僅在 updatecomponentUpdated 鉤子中可用。無(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)

  • oldVnode :上一個(gè)虛擬節(jié)點(diǎn),僅在 updatecomponentUpdated 鉤子中可用

注意!除了 el 之外,其它參數(shù)都應(yīng)該是只讀的,切勿進(jìn)行修改。如果需要在鉤子之間共享數(shù)據(jù),建議通過元素的 dataset 來(lái)進(jìn)行。

舉個(gè)例子,我們?cè)陧?xiàng)目中的按鈕需要通過權(quán)限來(lái)控制是否渲染,那么我們可以做一個(gè)權(quán)限指令來(lái)判斷是否渲染,

<template>
  <div>
    <button v-permission="['add_btn']">新增</button>
    <button v-permission="['edit_btn']">編輯</button>
    <button v-permission="['remove_btn']">刪除</button>
  </div>
</template>

<script>
// 模擬從后端拿到權(quán)限數(shù)據(jù)為一個(gè)數(shù)組,里面有新增以及編輯兩個(gè)按鈕權(quán)限:
const data = [ 'add_btn', 'edit_btn' ]

export default {
  name: '',
  directives: {
    //  定義一個(gè) permission 的指令
    permission: {
      // 在節(jié)點(diǎn)被插入父節(jié)點(diǎn)時(shí)調(diào)用
      inserted (el, binding, vnode) {
        const { value } = binding
        const permissionRoles = value

        const hasPermission = data.some(role => {
          return permissionRoles.includes(role)
        })
        // 如果沒有權(quán)限,則移除按鈕節(jié)點(diǎn)
        if (!hasPermission) {
          el.parentNode && el.parentNode.removeChild(el)
        }
      }
    }
  }
}
</script>

這樣,就完成了一個(gè)按鈕級(jí)別的權(quán)限管理, 自定義指令當(dāng)然還有更多的用處,比如按鈕的點(diǎn)擊波紋,按鈕點(diǎn)擊請(qǐng)求返回前的禁用,某節(jié)點(diǎn)加載時(shí)loading,如開頭所說(shuō)的,在你需要對(duì)普通 DOM 元素進(jìn)行底層操作的情況下,這時(shí)候就會(huì)用到自定義指令directive。

?著作權(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)容