Custom Directives,感覺好像有點猛?
感覺是可以做一些擴充功能吧!從 v-for 變成 v-money !!!
創建一個幫我賺錢的指令 www ~~
除了核心中預設的一組指令(如 v-model 或 v-show)之外,Vue 還允許您註冊自己的自定義指令。
我們在 Vue 中引入了兩種代碼重用的形式:組件和可組合功能。組件是主要的構建塊,而可組合功能則專注於重用有狀態的邏輯。另一方面,自定義指令主要用於重用涉及低級 DOM 訪問的邏輯。
自定義指令被定義為包含類似於組件的生命週期鉤子的物件。這些鉤子接收指令綁定的元素。下面是一個指令的例子,當元素被 Vue 插入到 DOM 中時,會將焦點放在輸入框上:
<script setup>
// 使 v-highlight 可在模板中使用
const vHighlight = {
mounted: (el) => {
el.classList.add('is-highlight')
}
}
</script>
<template>
<p v-highlight>這句話很重要!</p>
</template>
在 <script setup>
中,任何以 v 前綴開頭的駝峰命名變量都可以作為自定義指令使用。在上面的例子中,vHighlight
可以在模板中作為 v-highlight
使用。
如果您不使用 <script setup>
,可以使用 directives
選項來註冊自定義指令:
export default {
setup() {
/*...*/
},
directives: {
// 使 v-highlight 可在模板中使用
highlight: {
/* ... */
}
}
}
通常也會在應用層級全局註冊自定義指令:
const app = createApp({})
// 使 v-highlight 在所有組件中可用
app.directive('highlight', {
/* ... */
})
自定義指令應該僅在需要通過直接操作 DOM 才能實現所需功能時使用。
一個常見的例子是 v-focus
自定義指令,用於將元素設置為焦點。
<script setup>
// 在模板中啟用 v-focus
const vFocus = {
mounted: (el) => el.focus()
}
</script>
<template>
<input v-focus />
</template>
這個指令比 autofocus
屬性更有用,因為它不僅在頁面加載時有效,還在元素由 Vue 動態插入時有效!
當可能時,推薦使用內置指令(如 v-bind
)來進行聲明式模板編寫,因為它們更高效且更適合服務器渲染。
指令定義物件可以提供多個鉤子函數(所有的鉤子函數都是可選的):
const myDirective = {
// 在綁定元素的屬性或事件監聽器應用之前調用
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) {}
}
鉤子參數 指令鉤子函數接收以下參數:
el
: 綁定指令的元素。這可以用來直接操作 DOM。binding
: 包含以下屬性的物件。value
: 傳遞給指令的值。例如,在 v-my-directive="1 + 1"
中,值為 2。oldValue
: 之前的值,僅在 beforeUpdate
和 updated
鉤子中可用。無論值是否更改都可用。arg
: 傳遞給指令的參數(如果有)。例如,在 v-my-directive:foo
中,參數為 "foo"
。modifiers
: 包含修飾符的物件(如果有)。例如,在 v-my-directive.foo.bar
中,修飾符物件為 { foo: true, bar: true }
。instance
: 使用該指令的組件實例。dir
: 指令定義物件。vnode
: 表示綁定元素的底層 VNode。prevVnode
: 之前渲染時表示綁定元素的 VNode。僅在 beforeUpdate
和 updated
鉤子中可用。例如,考慮以下指令用法:
<template>
<div v-example:foo.bar="baz"></div>
</template>
binding
參數將是一個如下形狀的物件:
{
arg: 'foo',
modifiers: { bar: true },
value: /* `baz` 的值 */,
oldValue: /* 之前更新時 `baz` 的值 */
}
與內置指令類似,自定義指令的參數也可以是動態的。例如:
<template>
<div v-example:[arg]="value"></div>
</template>
這裡,指令參數將根據組件狀態中的 arg
屬性進行響應式更新。
除了 el
之外,應將這些參數視為只讀,不要修改它們。如果需要在鉤子之間共享信息,建議通過元素的 dataset
來實現。
通常,自定義指令在 mounted
和 updated
時具有相同的行為,且不需要其他鉤子。在這種情況下,我們可以將指令定義為一個函數:
<template>
<div v-color="color"></div>
</template>
<script>
app.directive('color', (el, binding) => {
// 這將在 `mounted` 和 `updated` 時調用
el.style.color = binding.value
})
</script>
如果你的指令需要多個值,你也可以傳遞一個 JavaScript 物件字面量。記住,指令可以接受任何有效的 JavaScript 表達式。
<template>
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
</template>
<script>
app.directive('demo', (el, binding) => {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
})
</script>
不建議
不建議在組件上使用自定義指令。當一個組件有多個根節點時,可能會出現意外行為。
當在組件上使用時,自定義指令將始終應用於組件的根節點,類似於fallthrough屬性。
<template>
<MyComponent v-demo="test" />
</template>
<!-- MyComponent 的模板 -->
<template>
<div> <!-- v-demo 指令將應用於此 -->
<span>我的組件內容</span>
</div>
</template>
請注意,組件可能有多個根節點。當應用於多根節點組件時,指令將被忽略,並且會拋出警告。與屬性不同,指令不能通過 v-bind="$attrs"
傳遞給其他元素。
這篇匆匆帶過~還沒有好好吸收~
實務上還沒應用過~實在不太清楚好不好用!
先了解有這個東西好了 www