更新元素的文字內容,v-text
透過設定元素的 textContent
屬性來工作,因此它將覆蓋元素中所有現有的內容。
<span v-text="msg"></span>
<!-- 等同於 -->
<span>{{msg}}</span>
v-html
<div v-html="htmlContent"></div>
Vue例項的資料屬性htmlContent
包含HTML字串,比如"<p>Hello World!</p>"
,那麼v-html就會使這個div
元素將會渲染出一個段落,包含文字"Hello World!",v-html
會強行覆蓋子元素。
注意事項
-
安全性:由於
v-html
會解析字串為HTML,因此如果這個字串包含使用者輸入的內容,那麼可能會有跨站指令碼(XSS)攻擊的風險。確保你信任你的資料來源,或者使用其他方式來清理和轉義HTML內容。 -
效能:頻繁地使用
v-html
可能會導致效能問題,因為它涉及到DOM的頻繁操作。如果你需要頻繁更新HTML內容,考慮使用其他方式來最佳化效能。 -
響應性:與
v-bind
或v-model
不同,v-html
不會對資料的每個變化都重新渲染HTML。如果資料物件的結構發生變化,可能需要使用其他方法來確保檢視的響應性。 -
使用場景:
v-html
適用於需要動態渲染HTML內容的場景,例如動態載入的富文字編輯器內容、使用者生成的內容等。
v-show
基於表示式值的真假性,來改變元素的可見性。
v-show
透過設定內聯樣式的 display
CSS 屬性來工作,當元素可見時將使用初始 display
值。
當條件改變時,也會觸發過渡效果。
因為v-show
避免了DOM的建立和銷燬,所以它在條件頻繁變化時效能更好
<div v-show="isShow">該元素由v-show控制是否展示</div>
v-if
v-if
是一個條件性渲染指令,它根據條件的真值來決定是否渲染元素。
當條件變化時,v-if
會觸發真實的DOM插入或刪除操作。如果條件由false
變為true
,Vue會建立元素並插入到DOM中;如果條件由true
變為false
,Vue會銷燬元素並從DOM中移除。
<div v-if="isShow">該元素由v-if控制是否渲染</div>
v-else
, v
-else-if 這兩者與 v-if
連用,效果等同於if - else 結構
v-on
v-on
是Vue.js中的一個指令,用於監聽DOM事件並在事件發生時執行一些JavaScript程式碼。它是Vue
響應式系統的一部分,允許開發者將事件處理邏輯繫結到Vue例項的資料上。
例如:繫結點選事件
<button v-on:click="method()">觸發點選事件</button>
<!-- 簡寫為 @ 某一事件件即可 -->
<button @click="method()">觸發點選事件</button>
v-on
無法直接繫結JavaScript中的函式,需要把JavaScript中的函式作為Vue
例項中的一部分(data,methods)後才能進行呼叫
v-on
自帶一個預設的event
引數,透過它可以獲取事件物件的屬性和方法:
-
event.target
:觸發事件的元素。 -
event.currentTarget
:事件繫結的元素,即當前元件的根元素。 -
event.type
:事件型別,如'click'
、'mouseover'
等。 -
event.preventDefault()
:阻止事件的預設行為。 -
event.stopPropagation()
:阻止事件繼續傳播到父元素。
v-bind
用於動態地繫結一個或多個屬性,它可以用來響應式地更新HTML元素的屬性。
繫結屬性
imageSrc
和 imageAlt
是Vue
例項的資料屬性
<!-- 繫結一個屬性 -->
<img v-bind:src="imageSrc">
<!-- 使用物件語法同時繫結多個屬性 -->
<img v-bind="{ src: imageSrc, alt: imageAlt }">
<!-- 使用簡寫 -->
<img :src="imageSrc" :alt="imageAlt">
繫結布林屬性
v-bind
可以非常智慧地處理它們的真值和假值。如果表示式的值為假(例如:null
、undefined
、false
、0
或空字串''
),布林屬性將不會被渲染。
<!-- 布林屬性 -->
<button v-bind:disabled="isButtonDisabled">Click me</button>
設定CSS類
active
類將根據 isActive
的值動態新增或移除,text-danger
類將根據 hasError
的值動態新增或移除。
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
繫結內聯樣式
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
物件與陣列語法
v-bind
的物件語法允許你傳遞一個物件,物件的屬性將被轉換為DOM元素的屬性。
new Vue({
data: {
buttonAttributes: {
type: 'button',
disabled: true,
title: 'Click me'
}
}
})
<button v-bind="buttonAttributes">Button</button>
v-bind
的陣列語法允許你傳遞一個陣列,陣列中的每個元素都將成為元素的一個屬性。
<button v-bind:[attributeName]="attributeValue">Button</button>
簡寫
v-bind
有一個簡寫形式,使用:
代替v-bind
v-for
用於基於源資料列表重複渲染一個元素或模板多次。它是Vue
響應式系統的一部分,能夠確保當源資料變化時,DOM也會相應地更新。
<span v-for="(item,index) in items" :key="index" :style="{margin: '4px'}">{{ item }}</span>
items
是Vue例項的一個陣列資料屬性。v-for
指令將為陣列中的每個元素渲染一個li
元素。每個li
都將顯示對應陣列元素的text
屬性。:key
是一個唯一鍵值,用於幫助Vue
跟蹤每個節點的身份,從而重用和重新排序現有元素。
遍歷物件
<ul>
<li v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</li>
</ul>
範圍迴圈
<div v-for="n in 10" :key="n">{{ n }}</div>
-
使用
key
屬性:當使用v-for
時,應該儘可能地為每個元素提供一個唯一的key
屬性。這有助於Vue
識別哪些元素是被改變、新增或移除的,從而提高渲染效率。 -
避免在
v-for
中使用非同步操作:在v-for
處理的資料上執行非同步操作可能會導致不可預見的結果。 -
不要在
v-for
中使用v-if
:每個v-for
元素都應該是獨立的,不應該與v-if
結合使用。如果需要根據條件渲染列表項,應該使用計算屬性來過濾列表。 -
效能考慮:雖然
v-for
非常強大,但渲染大量列表可能會對效能產生影響。在這種情況下,考慮使用虛擬滾動或其他最佳化技術。 -
響應性:確保
v-for
繫結的資料是響應式的。Vue
無法檢測以下更改:-
直接透過索引設定一個項:
items[index] = newValue
-
修改陣列的長度:
items.length = newLength
對於陣列的更改,應該使用響應式的方法,如:
Vue.set(items, index, newValue)
或更改陣列的方法,如:items.push(newItem)
。 -
key 屬性的必要性
使用key
的影響:
-
提高效能:
key
幫助Vue
識別哪些元素是被改變、新增或移除的。當列表資料變化時,Vue
可以使用key
來決定是否需要重新渲染元素,或者是否可以透過複用現有元素來提高效能。沒有key
時,Vue
可能會執行不必要的DOM
操作,導致效能下降。 -
避免元件狀態丟失:當列表項的順序變化或專案被重新排序時,如果使用
key
,Vue
能夠透過key
來跟蹤每個節點的身份,確保元件或元素的狀態(例如,輸入框的內容)得以保持。 -
確保正確的DOM更新:
key
確保Vue
可以精確地定位到需要更新的DOM元素,避免出現渲染錯誤。 -
提高可預測性:使用
key
可以提高列表渲染的可預測性,尤其是在動態內容變化時。
不使用key
的影響:
-
效能問題:沒有
key
時,Vue
在更新列表時會採用更通用的方法,這可能導致不必要的DOM操作,從而影響效能。 -
元件狀態丟失:在列表順序變化時,元件的狀態可能會丟失,因為
Vue
可能無法正確地識別哪些元素是被移動的,而不是被替換的。 -
渲染錯誤:在某些情況下,沒有
key
可能導致渲染錯誤,比如在刪除或插入列表項時,可能會導致其他項的顯示錯誤。 -
列表項閃爍:在某些動畫或過渡效果中,沒有
key
可能導致列表項在更新時出現閃爍現象。
何時使用key
:
-
當列表項的順序可能會變化時。
-
當列表項可能被動態新增或刪除時。
-
當列表項中包含元件,並且元件狀態需要保持時。
何時可以不使用key
:
-
當列表項的順序和數量在渲染後不會發生變化時。
-
當列表項非常簡單,不包含任何狀態或元件時。
v-model
用於在表單輸入和應用狀態之間建立雙向資料繫結。它是一個語法糖
,相當於同時繫結了 v-bind
和 v-on
指令。
<input v-model="message" placeholder="輸入一些文字">
<!-- 等價 -->
<input :value="message" @input="handleInput">
<!--
handleInput(event) {
console.log(event.target)
this.message = event.target.value;
}
-->
v-model 在 以下表單元素中同樣起作用
多行文字
<textarea v-model="message" placeholder="多行文字輸入"></textarea>
單選框、核取方塊
<!-- 單選按鈕 gender的值根據選擇結果,在男、女之間切換-->
<input type="radio" id="male" value="male" v-model="gender">
<label for="male">男</label>
<input type="radio" id="female" value="female" v-model="gender">
<label for="female">女</label>
<!-- 核取方塊 hobbies 是一個陣列,每個被選擇的元素都會被新增到 hobbies 中-->
<input type="checkbox" id="likes Football" value="Football" v-model="hobbies">
<label for="likes Football">足球</label>
<input type="checkbox" id="likes Basketball" value="Basketball" v-model="hobbies">
<label for="likes Basketball">籃球</label>
下拉框
<!-- 與單選框情況類似,沒有選擇是為空字串'' 或 預設值(設定了的話)-->
<select v-model="selectedCity">
<option value="New York">紐約</option>
<option value="San Francisco">舊金山</option>
<option value="Los Angeles">洛杉磯</option>
</select>
v-slot
<Component>
Click me! <!-- 插槽內容 -->
</FancyButton>
v-once
slot
是一種用於元件內容分發的 API,允許子元件在模板中預留一個或多個位置,這些位置可以被元件的使用者填充自定義的內容。這使得元件設計更加靈活和可複用
-
預設插槽
<FancyButton>
Click me! <!-- 插槽內容 -->
</FancyButton>
<button class="fancy-btn">
<slot></slot> <!-- 插槽出口 -->
</button>
Click me 會替換掉 slot
標籤 就像 下面程式碼所寫的那樣,插槽可以設定預設值,<slot>預設值</slot>
,當父元件沒有給子元件傳入數值的時候預設值才會起到作用,插槽可以訪問到父元件的資料,當你使用 插值表示式{{message}}
時可以進行動態的渲染子元件
<button class="fancy-btn">
Click me!
</button>
-
具名插槽
當我們需要用到多個插槽時,就需要對插槽進行區別,於是命名是一件很有必要的事情,對於這種場景,<slot>
元素可以有一個特殊的 attribute name
,用來給各個插槽分配唯一的 ID,以確定每一處要渲染的內容
<!-- -->
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
要為具名插槽傳入內容,我們需要使用一個含 v-slot
指令的 <template>
元素,並將目標插槽的名字傳給該指令
<BaseLayout>
<template v-slot:header>
<!-- header 插槽的內容放這裡 -->
</template>
</BaseLayout>
插槽的命名可以是動態的
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 縮寫為 -->
<template #[dynamicSlotName]>
...
</template>
</base-layout>
v-slot
有對應的簡寫 #
,因此 <template v-slot:header>
可以簡寫為 <template #header>
。
<BaseLayout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<template #default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>
最終渲染出的 子元素HTML結構 如下
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
-
條件插槽
有時你需要根據插槽是否存在來渲染某些內容。你可以結合使用 v-slot
屬性與 v-if
來實現。
就像這樣
<template>
<div class="card">
<div v-if="$slots.header" class="card-header">
<slot name="header" />
</div>
<div v-if="$slots.default" class="card-content">
<slot />
</div>
<div v-if="$slots.footer" class="card-footer">
<slot name="footer" />
</div>
</div>
</template>
當 header、footer 或 default 存在時,我們希望包裝它們以提供額外的樣式
-
作用域插槽
自定義指令
自定義指令允許你直接對元素進行低層次操作,包括但不限於DOM事件監聽、動態屬性繫結、樣式應用等。
directives: {
highlight: {
// 當被繫結的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
}
}
<input v-highlight>
自定義指令可以提供以下幾個鉤子函式:
-
bind
:只呼叫一次,指令第一次繫結到元素時呼叫,用以設定一次性的狀態。 -
inserted
:被繫結元素插入父節點時呼叫(僅保證父節點存在,但不一定已被插入文件中)。 -
update
:所在元件的VNode
更新時呼叫,但是可能發生在其子元件的VNode
更新之前,指令的值可能發生了變化,也可能沒有。 -
componentUpdated
:指令所在元件的VNode
及其子元件的VNode
全部更新後呼叫。 -
unbind
:只呼叫一次,指令與元素解綁時呼叫。
注意事項
-
自定義指令應該儘可能保持簡潔,避免進行復雜的操作。
-
自定義指令應該具有良好的封裝性,不應該依賴於Vue例項的外部狀態。
-
自定義指令不應該修改應用的狀態,它們應該隻影響繫結的元素。
修飾符
修飾符(Modifiers)是特殊的字尾,用於對指令的行為進行約束
.stop
阻止事件繼續傳播到父元素
<button @click.stop="doSomething">Stop Event Propagation</button>
.prevent
組織事件的預設行為
<form @submit.prevent="submitForm">Submit without reloading</form>
.capture
事件捕獲模式。事件從捕獲階段開始觸發,然後到達目標元素
<div @click.capture="doSomething">Capture Event</div>
.self
只有當事件是從元素本身觸發時才觸發回撥,而不是從子元素觸發
<div @click.self="handleClick">Click on this div</div>
.once
事件將只觸發一次,之後被移除
<button @click.once="doThisOnce">Do this once</button>
passive
告訴瀏覽器你不想阻止事件的預設行為,通常與scroll
事件結合使用以提高效能
<div @scroll.passive="handleScroll">Passive event listener</div>
.sync
用於建立一個同步的prop
,允許子元件更新父元件的繫結值
<child-component :value.sync="parentValue"></child-component>
.camel
自動將短橫線命名的屬性轉換為駝峰命名
<input :aria-label="label"> <!-- 轉換為 "ariaLabel" -->
.number
儘可能把輸入的字串轉化為數字
<input v-model.number="age" type="number">
.trim
過濾首尾輸入的空格
<input v-model.trim="message">