在Vue3 的 RFCs文檔中,Vue3中指令參數將支持動態參數。
基礎示例
<div v-bind:[key]="value"></div>
<div v-on:[event]="handler"></div>
<div v-slot:[slotName]="slotProps"></div>
為什么要這么做
在Vue3.0之前,Vue中的指令參數都是靜態設置的,當然也可以通過JavaScript的語法是達到動態參數的目的。
<div v-bind="{ [key]: value }"></div>
<div v-on="{ [event]: handler }"></div>
上面這種方法存在一些問題:
-
知道這個技巧的人並不多
-
代碼執行效率不高,如果在一個節點上同時綁定了動態參數和靜態參數,
h
函數就必須動態地迭代它並將其混合到現有的數據對象中。代碼如下:return h('div', { on: Object.assign({ click: onClick },{ [event]: handler }) })
而使用動態指令的語法后,生成的代碼如下:
return h('div',{ on: { click: onClick, [event]: handler } })
另外一個原因是:v-slot
沒有像 v-on
和 v-bind
一樣的對象語法,因為它的值是用來聲明slot作用域變量的。
應用示例
<div v-bind:[key]="value"></div>
<div :[key]="value"></div>
<div v-on:[event]="handler"></div>
<div @[event]="handler"></div>
<foo>
<template v-slot:[name]>
Hello
</template>
</foo>
<foo>
<template #[name]>
Default slot
</template>
</foo>
特殊情況 null
的處理
指令動態參數的值一般為string
,然而,如果我們允許使用null
來表示移除這個指令,將會是非常便利的。其他的non-string
類型的值都是錯誤的會產生一個警告。
null
只能用在v-bind
和 v-on
指令上,而不能用在v-slot
上。這是因為v-slot
不是一個綁定的屬性值而且也不能被移除。自定義指令可以自由決定如何處理non-string
的值,但是希望遵循慣例。
動態指令表達式書寫規范
理論上,可以使用任意復雜的JavaScript表達式來指定指令的參數,但是html屬性名稱不能包含空格和引號,所以,需要注意以下情況。
<div :[key + 'foo']="value"></div>
上面這種情況並不能達到我們期望的效果,可以下面這種寫法
<div :[`${key}foo`]="value"></div>
注意:太復雜的表達式,建議通過計算屬性進行預轉換