Vue3基礎(chǔ)
模板語法
插值
- 文本 =>
Mustache->{{ }} - 原始HTML =>
v-html="" - Attribute =>
v-bind - JavaScript表達(dá)式
指令(Directives) => v-attribute
- 參數(shù) =>
v-bind:參數(shù),v-on:參數(shù) - 動態(tài)參數(shù) =>
v-bind:[attributeName]=""- 不能含有空格,可使用計算屬性解決
- 修飾符 =>
.prevent<=>event.preventDefault()
縮寫
v-bind: <=> :
v-on: <=> @
Data Property 和方法
Data Property
$data
方法
methods => 綁定this
在定義
methods時應(yīng)避免使用箭頭函數(shù),因為這會阻止 Vue 綁定恰當(dāng)?shù)?this指向
防抖和節(jié)流
Vue 沒有內(nèi)置支持防抖和節(jié)流,但可以使用 Lodash 等庫來實現(xiàn)。
計算屬性和偵聽器
計算屬性 => computed
計算屬性緩存 vs 方法
計算屬性將基于它們的響應(yīng)依賴關(guān)系緩存。計算屬性只會在相關(guān)響應(yīng)式依賴發(fā)生改變時重新求值。這就意味著只要 計算屬性中的方法依賴的值 還沒有發(fā)生改變,多次訪問計算屬性中的方法時計算屬性會立即返回之前的計算結(jié)果,而不必再次執(zhí)行函數(shù)。
這也同樣意味著下面的計算屬性將永遠(yuǎn)不會更新,因為Date.now ()不是響應(yīng)式依賴。
相比之下,每當(dāng)觸發(fā)重新渲染時,調(diào)用方法將始終會再次執(zhí)行函數(shù)。-
計算屬性的 Setter
computed: { xxx: { // getter get() {}, // setter set(newValue) {} } }
偵聽器 => watch
- 計算屬性 vs 偵聽器
Vue 提供了一種更通用的方式來觀察和響應(yīng)當(dāng)前活動的實例上的數(shù)據(jù)變動:偵聽屬性。當(dāng)你有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動而變動時,watch很容易被濫用。然而,通常更好的做法是使用計算屬性而不是命令式的watch回調(diào)。
Class 與 Style 綁定
綁定 HTML Class
-
對象語法
<div :class="{ active: isActive }"></div>上面的語法表示
active這個 class 存在與否將取決于 data propertyisActive的 truthiness。 -
數(shù)組語法
<div :class="[activeClass, errorClass]"></div>data() { return { activeClass: 'active', errorClass: 'text-danger' } }
綁定內(nèi)聯(lián)樣式
-
對象語法
CSS property 名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用引號括起來) 來命名。<div :style="{ color: activeColor }"></div> -
數(shù)組語法
<div :style="[styleObject]"></div>data() { return { styleObject: { color: 'red' } } } 自動添加前綴
在:style中使用需要一個 vendor prefix (瀏覽器引擎前綴) 的 CSS property 時,Vue 將自動偵測并添加相應(yīng)的前綴。Vue 是通過運行時檢測來確定哪些樣式的 property 是被當(dāng)前瀏覽器支持的。如果瀏覽器不支持某個 property,Vue 會進(jìn)行多次測試以找到支持它的前綴。-
多重值
可以為 style 綁定中的 property 提供一個包含多個值的數(shù)組,常用于提供多個帶前綴的值,例如:<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>這樣寫只會渲染數(shù)組中最后一個被瀏覽器支持的值。在本例中,如果瀏覽器支持不帶瀏覽器前綴的 flexbox,那么就只會渲染
display: flex。
條件渲染
v-if
v-ifv-elsev-else-if
v-show
不同的是帶有 v-show 的元素始終會被渲染并保留在 DOM 中。v-show 只是簡單地切換元素的 display CSS property。
注意,v-show 不支持 <template> 元素,也不支持 v-else。
v-if vs v-show
v-if 是“真正”的條件渲染,因為它會確保在切換過程中,條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)乇讳N毀和重建。
v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變?yōu)檎鏁r,才會開始渲染條件塊。
相比之下,v-show 就簡單得多——不管初始條件是什么,元素總是會被渲染,并且只是簡單地基于 CSS 進(jìn)行切換。
一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運行時條件很少改變,則使用 v-if 較好。
v-if 與 v-for 一起使用
不推薦同時使用
v-if和v-for。
當(dāng) v-if 與 v-for 一起使用時,v-if 具有比 v-for 更高的優(yōu)先級。
列表渲染
用 v-for 把一個數(shù)組映射為一組元素
<ul>
<li v-for="(item, index) in items">
...
</li>
</ul>
在 v-for 里使用對象
<li v-for="(value, name, index) in myObject">
{{ index }}. {{ name }}: {{ value }}
</li>
維護(hù)狀態(tài)
當(dāng) Vue 正在更新使用 v-for 渲染的元素列表時,它默認(rèn)使用“就地更新”的策略。如果數(shù)據(jù)項的順序被改變,Vue 將不會移動 DOM 元素來匹配數(shù)據(jù)項的順序,而是就地更新每個元素,并且確保它們在每個索引位置正確渲染。
這個默認(rèn)的模式是高效的,但是只適用于不依賴子組件狀態(tài)或臨時 DOM 狀態(tài) (例如:表單輸入值) 的列表渲染輸出。
為了給 Vue 一個提示,以便它能跟蹤每個節(jié)點的身份,從而重用和重新排序現(xiàn)有元素,你需要為每項提供一個唯一的 key attribute:
<div v-for="item in items" :key="item.id">
<!-- 內(nèi)容 -->
</div>
建議盡可能在使用 v-for 時提供 key attribute,除非遍歷輸出的 DOM 內(nèi)容非常簡單,或者是刻意依賴默認(rèn)行為以獲取性能上的提升。
因為它是 Vue 識別節(jié)點的一個通用機制,key 并不僅與 v-for 特別關(guān)聯(lián)。后面我們將在指南中看到,它還具有其它用途。
更多
keyattribute 的細(xì)節(jié)用法請移步至key的 API 文檔。
數(shù)組更新檢測
-
變更方法
Vue 將被偵聽的數(shù)組的變更方法進(jìn)行了包裹,所以它們也將會觸發(fā)視圖更新。這些被包裹過的方法包括:push()pop()shift()unshift()splice()sort()reverse()
替換數(shù)組
變更方法,顧名思義,會變更調(diào)用了這些方法的原始數(shù)組。相比之下,也有非變更方法,例如filter()、concat()和slice()。它們不會變更原始數(shù)組,而總是返回一個新數(shù)組。當(dāng)使用非變更方法時,可以用新數(shù)組替換舊數(shù)組。
顯示過濾/排序后的結(jié)果
計算屬性
<li v-for="n in evenNumbers" :key="n">{{ n }}</li>
data() {
return {
numbers: [ 1, 2, 3, 4, 5 ]
}
},
computed: {
evenNumbers() {
return this.numbers.filter(number => number % 2 === 0)
}
}
在計算屬性不適用的情況下 (例如,在嵌套的 v-for 循環(huán)中) 你可以使用一個方法:
<ul v-for="numbers in sets">
<li v-for="n in even(numbers)" :key="n">{{ n }}</li>
</ul>
data() {
return {
sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
}
},
methods: {
even(numbers) {
return numbers.filter(number => number % 2 === 0)
}
}
在 v-for 里使用值的范圍
v-for 也可以接受整數(shù)。在這種情況下,它會把模板重復(fù)對應(yīng)次數(shù)。
<div id="range" class="demo">
<span v-for="n in 10" :key="n">{{ n }} </span>
</div>
在 <template> 中使用 v-for
類似于 v-if,你也可以利用帶有 v-for 的 <template> 來循環(huán)渲染一段包含多個元素的內(nèi)容。
v-for 與 v-if 一同使用
當(dāng)它們處于同一節(jié)點,v-if 的優(yōu)先級比 v-for 更高,這意味著 v-if 將沒有權(quán)限訪問 v-for 里的變量:
<!-- 這將拋出一個錯誤,因為“todo” property 沒有在實例上定義 -->
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>
可以把 v-for 移動到 <template> 標(biāo)簽中來修正:
<template v-for="todo in todos" :key="todo.name">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
在組件上使用 v-for
事件處理
監(jiān)聽事件 => @
事件處理方法
@event="handle" -> methods: {handle() { } }
內(nèi)聯(lián)處理器中的方法
@event="handle(args)"
@click="handle(args, $event)"
有時也需要在內(nèi)聯(lián)語句處理器中訪問原始的 DOM 事件??梢杂锰厥庾兞?$event 把它傳入方法:
methods: {
handle(args, event) {
// 原生事件 event
}
多事件處理器
事件處理程序中可以有多個方法,這些方法由逗號運算符分隔:
<!-- 這兩個 one() 和 two() 將執(zhí)行按鈕點擊事件 -->
<button @click="one($event), two($event)">
Submit
</button>
// ...
methods: {
one(event) {
// 第一個事件處理器邏輯...
},
two(event) {
// 第二個事件處理器邏輯...
}
}
事件修飾符
-
.stop: 阻止單擊事件繼續(xù)冒泡; -
.prevent: 提交事件不再重載頁面; -
.capture: 添加事件監(jiān)聽器時使用事件捕獲模式,即內(nèi)部元素觸發(fā)的事件先在此處理,然后才交由內(nèi)部元素進(jìn)行處理; -
.self: 只當(dāng)在 event.target 是當(dāng)前元素自身時觸發(fā)處理函數(shù),即事件不是從內(nèi)部元素觸發(fā)的; -
.once: 點擊事件將只會觸發(fā)一次; -
.passive: 對應(yīng)addEventListener中的 passive 選項。
修飾符可以串聯(lián),使用修飾符時,順序很重要;相應(yīng)的代碼會以同樣的順序產(chǎn)生。
按鍵修飾符
<!-- 只有在 `key` 是 `Enter` 時調(diào)用 `vm.submit()` -->
<input @keyup.enter="submit" />
可以直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉(zhuǎn)換為 kebab-case 來作為修飾符。
<input @keyup.page-down="onPageDown" />
- 按鍵別名
Vue 為最常用的鍵提供了別名:.enter.tab-
.delete(捕獲“刪除”和“退格”鍵) .esc.space.up.down.left.right
系統(tǒng)修飾鍵
.ctrl.alt.shift-
.meta: meta 對應(yīng) command 鍵 (?)。在 Windows 系統(tǒng)鍵盤 meta 對應(yīng) Windows 徽標(biāo)鍵 (?)。
請注意修飾鍵與常規(guī)按鍵不同,在和
keyup事件一起用時,事件觸發(fā)時修飾鍵必須處于按下狀態(tài)。換句話說,只有在按住ctrl的情況下釋放其它按鍵,才能觸發(fā)keyup.ctrl。而單單釋放ctrl也不會觸發(fā)事件。
.exact修飾符
.exact修飾符允許你控制由精確的系統(tǒng)修飾符組合觸發(fā)的事件。-
鼠標(biāo)按鈕修飾符
.left.right-
.middle
這些修飾符會限制處理函數(shù)僅響應(yīng)特定的鼠標(biāo)按鈕。
表單輸入綁定 => v-model
v-model會忽略所有表單元素的value、checked、selectedattribute 的初始值。它將始終將當(dāng)前活動實例的數(shù)據(jù)作為數(shù)據(jù)來源。你應(yīng)該通過 JavaScript 在組件的data選項中聲明初始值。
v-model 在內(nèi)部為不同的輸入元素使用不同的 property 并拋出不同的事件:
- text 和 textarea 元素使用
valueproperty 和input事件; - checkbox 和 radio 使用
checkedproperty 和change事件; - select 字段將
value作為 prop 并將change作為事件。
對于需要使用輸入法 (如中文、日文、韓文等) 的語言,你會發(fā)現(xiàn)
v-model不會在輸入法組織文字過程中得到更新。如果你也想響應(yīng)這些更新,請使用input事件監(jiān)聽器和value綁定來替代v-model。
值綁定
對于單選按鈕,復(fù)選框及選擇框的選項,v-model 綁定的值通常是靜態(tài)字符串 (對于復(fù)選框也可以是布爾值)。
修飾符
-
.lazy:v-model在每次input事件觸發(fā)后將輸入框的值與數(shù)據(jù)進(jìn)行同步。你可以添加lazy修飾符,從而轉(zhuǎn)為在change事件之后進(jìn)行同步; -
.number:自動將用戶的輸入值轉(zhuǎn)為數(shù)值類型; -
.trim:自動過濾用戶輸入的首尾空白字符。
組件基礎(chǔ)
組件的復(fù)用
組件的組織
有兩種組件的注冊類型:全局注冊和局部注冊。
通過 Prop 向子組件傳遞數(shù)據(jù) => props
監(jiān)聽子組件事件 => $emit()
使用事件拋出一個值 =>
$emit()-
在組件上使用
v-model
自定義事件也可以用于創(chuàng)建支持v-model的自定義輸入組件。為了讓它正常工作,這個組件內(nèi)的
<input>必須:- 將其
valueattribute 綁定到一個名叫modelValue的 prop 上 - 在其
input事件被觸發(fā)時,將新的值通過自定義的update:modelValue事件拋出
app.component('custom-input', { props: ['modelValue'], emits: ['update:modelValue'], template: ` <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" > ` })<custom-input v-model="searchText"></custom-input>在該組件中實現(xiàn)
v-model的另一種方法是使用computedproperty 的功能來定義 getter 和 setter。get方法應(yīng)返回modelValueproperty,set方法應(yīng)該觸發(fā)相應(yīng)的事件。app.component('custom-input', { props: ['modelValue'], emits: ['update:modelValue'], template: ` <input v-model="value"> `, computed: { value: { get() { return this.modelValue }, set(value) { this.$emit('update:modelValue', value) } } } }) - 將其
通過插槽分發(fā)內(nèi)容 => <slot></slot>
動態(tài)組件 => :is
- 已注冊組件的名字,或
- 一個組件選項對象