v-bind
是非常常見的內置指令,常用於 HTML attribute,
例如 style
, class
, props
, etc.。
放的位置會在 element <>
裡面,無法單獨存在。
在版本更新迭代如此迅速的情況下,大家可能會見到的寫法是這樣:
<img :src="imageSrc" /> // 常見用法,簡寫。
<img v-bind:src="imageSrc" /> // 原本寫法。
▲ v-bind 不同寫法。
如果你是第一次看到這種語法,你可能會好奇為甚麼前面要有冒號
正常情況如果你不加上冒號,傳入值就會是純字串,
就跟一般的 HTML attribute 一樣。
▲ 冒號使用在 HTML attribute 上表現的差異。
而當我們加上冒號同時等於 v-bind:src="imageSrc"
,
當然這個語法可以有效使用,是因為 Vue 做了處理。
對於 v-bind:
後的屬性會利用 in
運算符,
來檢查是否有已定義好的同名 HTML property,
有的話就會對於那個 property 賦值,不然就會變成 attribute。
//node_modules>@vue>runtime-dom>dist>runtime-dom.cjs.js
function shouldSetAsProp(el, key, value, isSVG) {
// 其餘判斷邏輯 ...
return key in el; // 這邊將會做處理
}
▲ v-bind 背後使用 in 運算符進行處理的原始碼
//node_modules>@vue>runtime-dom>dist>runtime-dom.cjs.js
const patchProp = (el, key, prevValue, nextValue, namespace, parentComponent) => {
// 其餘程式碼
// 下面這段會去根據 shouldSetAsProp() 回傳結果決定要把這個 v-bind: 歸類在 props 或是 attrs
} else if (key[0] === "." ? (key = key.slice(1), true) : key[0] === "^" ? (key = key.slice(1), false) : shouldSetAsProp(el, key, nextValue, isSVG)) {
patchDOMProp(el, key, nextValue);
if (!el.tagName.includes("-") && (key === "value" || key === "checked" || key === "selected")) {
patchAttr(el, key, nextValue, isSVG, parentComponent, key !== "value");
}
// 其餘程式碼
};
▲ v-bind 根據回傳結果歸類之原始碼
一但今天可以傳入的是動態參數,那我們今天可以做的彈性就變得非常高了。
<div :class="{ active: isActive }"></div>
<!-- 當 isActive 等於 true,那active 這個 class 就會存在 -->
<div :class="[baseClass, themeClass]"></div>
<div :class="[{ [activeClass]: isActive }, errorClass]"></div>
<!-- 你也可以傳入 array、object -->
▲ v-bind 動態參數範例 1
<script setup>
import { ref, computed } from 'vue'
const isActive = ref(false)
const isError = ref(false)
// 當然你也可以傳入計算屬性
const cardClass = computed(() => {
return {
'bg-white': !isActive.value && !isError.value,
'bg-green-100 border-green-500': isActive.value,
'bg-red-100 border-red-500': isError.value,
}
})
</script>
<template>
<div :class="cardClass">
</template>
▲ v-bind 動態參數範例 2
:style
使用時機
那如果我們今天要寫 inline-style
該怎麼運用這個動態語法呢,
或是這樣反問,什麼情況我們會需要動態 inline-style
呢?
假設一種情況是你今天使用的套件,
他初始情況就是去在 DOM 元素的 style
attribute 做更改。
那考慮到 CSS 權重問題, 除非你加上 !important
,
不然只能透過 inline-style
來修改了。
<script setup>
import { ref } from 'vue'
const selectedColor = ref('red');
const fontSize = ref(24);
</script>
<template>
<p :style="{ color: activeColor, fontSize: fontSize + 'px' }"></p>
<!-- 跟 :class 一樣你也可以傳入 array、object -->
</template>
▲ 動態綁定 style 範例
CSS 權重
瀏覽器會根據優先級來決定哪個樣式會被應用到 DOM 元素上
在 Vue 過氣前要學的第十件事 - 從打好基本功開始 / Directives 中我們提到,
文本插值的 雙括號 讓你可以動態替換內容。
但如果今天你是要以 props
或是 attrs
的形式傳遞給子元件,
就無法使用 {{}}
而是要以 v-bind做動態綁定,就跟我們上面做的一樣。
這種情況 Vue 會將兩者視為等價的。
▲ 動態參數根據使用情境有不同的寫法,source。
透過 v-bind
或簡寫的 :
語法,
我們可以非常靈活地把資料綁定到 HTML 屬性、DOM property 或元件的 props 上。
Vue 在底層會自動判斷該走 property 還是 attribute,確保動態值能正確更新,
理解這套機制,不僅能讓我們更好地控制 DOM 屬性和樣式,
也能在組件開發中正確傳遞資料,避免意外錯誤。
其實這個篇章雖然是非常基礎,但我自己在寫的時候還是卡了一下
這也告訴我自己其實我沒有這麼紮實的清楚這些東西,也算是重新複習一下。
如果你喜歡這個系列或是想看我發瘋,歡迎按下 訂閱
一起走完這三十天吧。
v-bind
簡寫為何 ?