前言

  在vue專案中我們經常使用到 v-show ,v-if,v-for等內建的指令,除此之外vue還提供了非常方便的自定義指令,供我們對普通的dom元素進行底層的操作。使我們的日常開發變得更加方便快捷。本文就來總結一下自定義指令的使用方法及常用的場景。

正文

  1.全域性註冊

  這裡全域性註冊一個指令,用於使用該指令的元素加一個紅色邊框,通過指令操作樣式。

  <div id="app">
<h1 type="text" v-red>我是h1元素</h1>
<div v-red>我是div元素</div>
<p v-red>我是p元素</p><br>
<input type="text" v-red><br>
</div>
<script>
Vue.directive("red", {
// 指令的定義
inserted: function (el) {
console.log(111);
el.style.border = "1px solid red"
}
})
new Vue({
el: "#app",
data() {
return {
}
},
methods: {
}
})
</script>

  執行結果如下:

  上面的程式碼中通過 Vue.directive 方法註冊了一個全域性的指令,該函式接收兩個引數,第一個引數為指令名稱,在元素中通過 " v-名稱 " 繫結元素,第二個引數為對繫結元素進行處理的鉤子函式,後面會有詳細介紹。

  2.區域性註冊

  和全域性註冊指令基本一樣,只是作用範圍不同而已,這裡在元件內部註冊一個自定義指令用於給元件內部的繫結元素設定藍色邊框。

 <div id="app">
<border-item></border-item>
</div>
<script>
Vue.directive("red", {
// 指令的定義
inserted: function (el) {
console.log(111);
el.style.border = "1px solid red"
}
})
// 定義子元件
Vue.component("border-item", {
directives: {
blue: {
// 指令的定義
inserted: function (el) {
el.style.border = "1px solid blue"
}
}
},
template: `<div>
<h1 v-blue>我是子元件h1元素</h1>
<div v-blue>我是子元件div元素</div>
<p v-blue>我是子元件p元素</p><br>
子元件<input type="text" v-blue><br>
<p v-blue>我是子元件h1元素,我同時使用了全域性和區域性自定義指令</p>
</div>`
})
new Vue({
el: "#app",
data() {
return {
}
},
methods: {
}
})
</script>

  執行結果如下:

  通過上面的程式碼,在子元件內部通過 directives 物件註冊了一個給繫結元素設定藍色邊框的元件,該物件中傳入鍵值對,其中鍵表示指令名稱,通過" v-名稱 "使用,其值對應一個物件,物件內部為指令的相關鉤子函式。後面詳解鉤子函式。

  注意:當同一個元素及使用了全域性指令和區域性指令對統一屬性進行操作的時候,會優先使用區域性自定義指令,這裡採用就近原則,區域性指令會優先於全域性指令對統一屬性操作的呼叫。

  3.鉤子函式及引數設定

  看了上面的介紹我們值都了directive的用法,但是裡面的鉤子函式還需要清楚,只有明白了鉤子函式的呼叫時機,才能定義出更加完美的指令。

  一個指令定義物件可以提供如下幾個鉤子函式 (均為可選):

* bind:只調用一次,指令第一次繫結到元素時呼叫。在這裡可以進行一次性的初始化設定。

* inserted:被繫結元素插入父節點時呼叫 (僅保證父節點存在,但不一定已被插入文件中)。

* update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前後      的值來忽略不必要的模板更新 (詳細的鉤子函式引數見下)。

* componentUpdated:指令所在元件的 VNode 及其子 VNode 全部更新後呼叫。

* unbind:只調用一次,指令與元素解綁時呼叫。

  鉤子函式引數 指令鉤子函式會被傳入以下引數:
              *  el:指令所繫結的元素,可以用來直接操作 DOM。
              *  binding:一個物件,包含以下 property:
              *  name:指令名,不包括 v- 字首。
              *  value:指令的繫結值,例如:v-my-directive="1 + 1" 中,繫結值為 2。
              *  oldValue:指令繫結的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
              *  expression:字串形式的指令表示式。例如 v-my-directive="1 + 1" 中,表示式為 "1 + 1"。
              *  arg:傳給指令的引數,可選。例如 v-my-directive:foo 中,引數為 "foo"。
              *  modifiers:一個包含修飾符的物件。例如:v-my-directive.foo.bar 中,修飾符物件為 { foo: true, bar: true }。
              *  vnode:Vue 編譯生成的虛擬節點。
              *  oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。

  4.靈活用法

  (1)動態指令引數

  指令的引數可以是動態的。例如,在 v-mydirective:[argument]="value" 中,argument 引數可以根據元件例項資料進行更新!這使得自定義指令可以在應用中被靈活使用。下面例子中分別設定指令實現元素的邊框繫結和元素的背景屬性繫結。
 <div id="app">
<h1 v-border="redBorder">我是動態指令引數的元素1</h1>  
<h1 v-color:[pro]="redBg">我是動態指令引數的元素2</h1>
</div>
<script>
Vue.directive("border", {
bind: function (el, binding, vnode) {
console.log("el", el);
console.log("binding", binding);
console.log("vnode", vnode);
el.style.border = binding.value
}
})
Vue.directive("color", {
bind: function (el, binding, vnode) {
console.log("el", el);
console.log("binding", binding);
console.log("vnode", vnode);
el.style[binding.arg] = binding.value
}
})
new Vue({
el: "#app",
data() {
return {
redBorder: "1px solid red",
pro: "backgroundColor",
redBg: "green"
}
},
methods: {
}
})
</script>

  執行結果如下:

  順便看下列印的引數:

  上面的程式碼中通過兩種方式介紹了動態引數自定義指令的方法,使用十分靈活,根據實際需要選擇合適的方式。

  (2)函式簡寫方式

  在很多時候,你可能想在 bind 和 update 時觸發相同行為,而不關心其它的鉤子。比如這樣寫:

    Vue.directive("border",
function (el, binding, vnode) {
el.style.border = binding.value
}
)

  (3)物件字面量方式

  在繫結自定義指令的元素紅傳入一個物件的格式的資料,然後在函式簡寫方式中使用。

<div id="app">
<h1 v-color="{ color: 'red', text: 'hello!' }">我是物件字面量形式</h1>
</div>
<script>
// 物件字面量
Vue.directive('color', function (el, binding) {
console.log(binding.value.color) // => "red"
console.log(binding.value.text) // => "hello!"
el.style.color = binding.value.color
el.innerHTML = binding.value.text
})
new Vue({
el: "#app",
data() {
return {
}
},
methods: {
}
})
</script>

  執行結果如下:

  5.使用場景

  除了上面的使用場景外,比如我們在專案中通過自定義指令來控制一個前端頁面的許可權問題,在指令中設定一個引數,當頁面載入或者提交事件觸發的時候,首先執行該自定義指令的事件,去請求校驗是否有這個許可權,做出相應的操作。使用的地方還有好多,需要在專案中不斷練習,可能有別的替代的方法而不被運用,這就需要我們不斷去學習鞏固這些基礎知識,應用最優的解決方法去完成專案。

寫在最後

  以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。最後,大家中秋節快樂!!!