指令

CaoJianbang發表於2024-10-24

帶v-的特殊屬性即為指令,常見的指令有v-if,v-show,v-html,v-text,v-slot,v-bind,v-on,v-model等等,也可自定義指令。一個指令的任務是在其表示式的值變化時響應式地更新 DOM。

除了name為必須外,其他的都可以沒有,也可以有,修飾符可以有多個; v-focus v-aa.bb v-aa:aa.bb 都合法

name: 指令名稱,v-開頭的部分。v-bind: 簡寫: ;v-on:簡寫@

argument: 引數:開頭的部分,為字串型別,如果為:[xxx] 及為動態引數,xxx必須是字串型別,且不能有空格等不合法字元。而且必須只能是小寫(大寫會被html轉成小寫,導致後面獲取不到)

modifier:修飾符.開頭的部分

value:值 =開頭的部分,可以為任意型別,比如@click='clickEvent' clickEvent就是個函式型別,複雜資料可用物件

自定義指令:

<script setup>
// 在模板中啟用 v-focus
const vFocus = {
  mounted: (el) => el.focus()
}
</script>

<template>
  <input v-focus />
</template>

在 <script setup> 中,任何以 v 開頭的駝峰式命名的變數都可以被用作一個自定義指令。在上面的例子中,vFocus 即可以在模板中以 v-focus 的形式使用。

1,全域性自定義指令

const app = createApp({})

// 使 v-focus 在所有元件中都可用
app.directive('focus', {
  /* ... */
})

2,指令鉤子

指令鉤子函式引數說明:除了el,其他的值都不能改變

el:繫結到的元素,可用來直接操作dom

binding:物件包含下面幾個屬性

{

  value : 指令值;

  oldValue: 改動前的值,僅用於updated,beforeupdate兩個鉤子中

  arg:指令引數字串v-my-directive:foo,值為foo

  modifiers:修飾符物件,比如v-my-directive.foo.bar中,修飾符物件是 { foo: true, bar: true }

  instance:使用該指令的元件例項

  dir:指令的定義物件

}

vnode:繫結元素的底層VNode.

prevVnode:之前渲染中指令所繫結元素的VNode,僅用於updated,beforeupdate兩個鉤子中

const myDirective = {
  // 在繫結元素的 attribute 前
  // 或事件監聽器應用前呼叫
  created(el, binding, vnode) {
    // 下面會介紹各個引數的細節
  },
  // 在元素被插入到 DOM 前呼叫
  beforeMount(el, binding, vnode) {},
  // 在繫結元素的父元件
  // 及他自己的所有子節點都掛載完成後呼叫
  mounted(el, binding, vnode) {},
  // 繫結元素的父元件更新前呼叫
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在繫結元素的父元件
  // 及他自己的所有子節點都更新後呼叫
  updated(el, binding, vnode, prevVnode) {},
  // 繫結元素的父元件解除安裝前呼叫
  beforeUnmount(el, binding, vnode) {},
  // 繫結元素的父元件解除安裝後呼叫
  unmounted(el, binding, vnode) {}
}

3,簡化形式,自定義指令常在mounted和updated上實現相同的行為,不需要其他鉤子,可做下簡化

<div v-color="color"></div>

app.directive('color', (el, binding) => {
  // 這會在 `mounted` 和 `updated` 時都呼叫
  el.style.color = binding.value
})

4,對子元件中使用,不建議

對子元件使用,會透傳到子元件的根元素(如果子元件有多個根元素,將導致透傳失敗,併發出警告)