Vue2 指令

XiSoil發表於2024-08-18
v-text

更新元素的文字內容,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會強行覆蓋子元素。

注意事項

  1. 安全性:由於v-html會解析字串為HTML,因此如果這個字串包含使用者輸入的內容,那麼可能會有跨站指令碼(XSS)攻擊的風險。確保你信任你的資料來源,或者使用其他方式來清理和轉義HTML內容。

  2. 效能:頻繁地使用v-html可能會導致效能問題,因為它涉及到DOM的頻繁操作。如果你需要頻繁更新HTML內容,考慮使用其他方式來最佳化效能。

  3. 響應性:與v-bindv-model不同,v-html不會對資料的每個變化都重新渲染HTML。如果資料物件的結構發生變化,可能需要使用其他方法來確保檢視的響應性。

  4. 使用場景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元素的屬性。

繫結屬性

imageSrcimageAltVue例項的資料屬性

<!-- 繫結一個屬性 -->
<img v-bind:src="imageSrc">
<!-- 使用物件語法同時繫結多個屬性 -->
<img v-bind="{ src: imageSrc, alt: imageAlt }">
<!-- 使用簡寫 -->
<img :src="imageSrc" :alt="imageAlt">

繫結布林屬性

v-bind 可以非常智慧地處理它們的真值和假值。如果表示式的值為假(例如:nullundefinedfalse0 或空字串''),布林屬性將不會被渲染。

<!-- 布林屬性 -->
<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>
  1. 使用 key 屬性:當使用 v-for 時,應該儘可能地為每個元素提供一個唯一的 key 屬性。這有助於Vue識別哪些元素是被改變、新增或移除的,從而提高渲染效率。

  2. 避免在 v-for 中使用非同步操作:在 v-for 處理的資料上執行非同步操作可能會導致不可預見的結果。

  3. 不要在 v-for 中使用 v-if:每個 v-for 元素都應該是獨立的,不應該與 v-if 結合使用。如果需要根據條件渲染列表項,應該使用計算屬性來過濾列表。

  4. 效能考慮:雖然 v-for 非常強大,但渲染大量列表可能會對效能產生影響。在這種情況下,考慮使用虛擬滾動或其他最佳化技術。

  5. 響應性:確保 v-for 繫結的資料是響應式的。Vue 無法檢測以下更改:

    • 直接透過索引設定一個項:items[index] = newValue

    • 修改陣列的長度:items.length = newLength

    對於陣列的更改,應該使用響應式的方法,如:Vue.set(items, index, newValue) 或更改陣列的方法,如:items.push(newItem)

key 屬性的必要性

使用key的影響:

  1. 提高效能key幫助Vue識別哪些元素是被改變、新增或移除的。當列表資料變化時,Vue可以使用key來決定是否需要重新渲染元素,或者是否可以透過複用現有元素來提高效能。沒有key時,Vue可能會執行不必要的DOM操作,導致效能下降。

  2. 避免元件狀態丟失:當列表項的順序變化或專案被重新排序時,如果使用keyVue能夠透過key來跟蹤每個節點的身份,確保元件或元素的狀態(例如,輸入框的內容)得以保持。

  3. 確保正確的DOM更新key確保Vue可以精確地定位到需要更新的DOM元素,避免出現渲染錯誤。

  4. 提高可預測性:使用key可以提高列表渲染的可預測性,尤其是在動態內容變化時。

不使用key的影響:

  1. 效能問題:沒有key時,Vue在更新列表時會採用更通用的方法,這可能導致不必要的DOM操作,從而影響效能。

  2. 元件狀態丟失:在列表順序變化時,元件的狀態可能會丟失,因為Vue可能無法正確地識別哪些元素是被移動的,而不是被替換的。

  3. 渲染錯誤:在某些情況下,沒有key可能導致渲染錯誤,比如在刪除或插入列表項時,可能會導致其他項的顯示錯誤。

  4. 列表項閃爍:在某些動畫或過渡效果中,沒有key可能導致列表項在更新時出現閃爍現象。

何時使用key

  • 當列表項的順序可能會變化時。

  • 當列表項可能被動態新增或刪除時。

  • 當列表項中包含元件,並且元件狀態需要保持時。

何時可以不使用key

  • 當列表項的順序和數量在渲染後不會發生變化時。

  • 當列表項非常簡單,不包含任何狀態或元件時。

v-model

用於在表單輸入和應用狀態之間建立雙向資料繫結。它是一個語法糖,相當於同時繫結了 v-bindv-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">

相關文章