title: Vue 3指令與事件處理
date: 2024/5/25 18:53:37
updated: 2024/5/25 18:53:37
categories:
- 前端開發
tags:
- Vue3基礎
- 指令詳解
- 事件處理
- 高階事件
- 實戰案例
- 最佳實踐
- 效能最佳化
第1章 Vue 3基礎
1.1 Vue 3簡介
Vue 3 是一個由尤雨溪(尤大)領導的開源JavaScript框架,它專注於構建使用者介面。相較於Vue 2,Vue 3在核心理念上保持一致,但對一些底層實現進行了重大最佳化,包括:
- SFC(Single File Component) : Vue 3繼續支援SFC模式,將元件的模板、樣式和邏輯整合在一個檔案中。
- Composition API: 引入新的程式設計模型,強調元件內部狀態的可組合性,而非依賴於props和data。
- TypeScript支援: 提供了更好的型別系統,方便開發者編寫型別安全的程式碼。
- Performance: 透過移除一些不必要的依賴,提高了效能,特別是對於大型應用。
1.2 安裝與配置
1.2.1 環境準備
- Node.js: Vue 3需要Node.js環境,建議使用最新版本。
- 使用npm或yarn: 作為包管理器,安裝Vue CLI(命令列工具)。
1.2.2 Vue CLI安裝
- 開啟終端(或命令提示符):
npm install -g @vue/cli
- 或者使用yarn:
yarn global add @vue/cli
1.2.3 建立專案
- 建立一個新的Vue 3專案:
vue create my-project
- 進入專案目錄:
cd my-project
1.2.4 配置基本檔案
- 修改
src/main.js
,引入Vue例項並啟動應用:
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
1.3 模板語法
1.3.1 JSX-like模板 Vue 3的模板語法採用類似React的JSX語法,但更簡潔。如建立一個Hello World元件:
<template>
<div>Hello, {{ name }}!</div>
</template>
<script>
export default {
data() {
return {
name: 'World',
};
},
};
</script>
{{ }}
用於插值表示式,{{{ }}}
用於文字插值。<div>
是標籤,<template>
用於包裹元件內容。
1.3.2 簡化模板 Vue 3還支援更簡潔的模板語法,如:
<template>
<div>Hello, {{ name }}!</div>
</template>
<script>
export default {
data() {
return { name: 'World' };
},
};
</script>
- 省略了
<script>
標籤內的export default
和data
。
第2章 Vue 3指令
2.1 內建指令
Vue 3提供了多種內建指令,用於控制DOM的行為和渲染。以下是一些常用的內建指令:
AD:漫畫首頁
2.1.1 v-bind
v-bind
指令用於動態地繫結一個或多個屬性,或者一個元件 prop 到表示式。在Vue 3中,v-bind
可以簡寫為 :
。
示例:
<template>
<img :src="imageSrc" alt="Image">
</template>
<script>
export default {
data() {
return {
imageSrc: 'https://example.com/image.jpg',
};
},
};
</script>
2.1.2 v-model
v-model
指令用於在表單控制元件或者元件上建立雙向資料繫結。
示例:
<template>
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: '',
};
},
};
</script>
2.1.3 v-on
v-on
指令用於監聽DOM事件,並在觸發時執行一些JavaScript程式碼。v-on
可以簡寫為 @
。
示例:
<template>
<button @click="incrementCounter">Click me</button>
</template>
<script>
export default {
data() {
return {
counter: 0,
};
},
methods: {
incrementCounter() {
this.counter++;
},
},
};
</script>
2.1.4 v-show與v-if
v-show
和 v-if
指令用於條件性地渲染一塊內容。v-show
是透過CSS控制元素的顯示與隱藏,而 v-if
則是透過建立或銷燬DOM元素來控制。
示例:
<template>
<p v-show="isVisible">This is shown by v-show</p>
<p v-if="isVisible">This is shown by v-if</p>
</template>
<script>
export default {
data() {
return {
isVisible: true,
};
},
};
</script>
2.1.5 v-for
v-for
指令用於基於源資料多次渲染元素或模板塊。
示例:
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
],
};
},
};
</script>
2.1.6 v-text與v-html
v-text
指令用於更新元素的 textContent。v-html
指令用於更新元素的 innerHTML。
示例:
<template>
<p v-text="textContent"></p>
<p v-html="htmlContent"></p>
</template>
<script>
export default {
data() {
return {
textContent: 'This is text content',
htmlContent: '<span>This is HTML content</span>',
};
},
};
</script>
透過這些內建指令,Vue 3允許開發者以宣告式的方式控制DOM,使得程式碼更加簡潔和易於維護。
2.2 自定義指令
除了內建指令,Vue 3還允許開發者建立自定義指令。自定義指令可以用於執行更多複雜的DOM操作。
2.2.1 建立自定義指令
可以使用 directives
選項在元件中註冊自定義指令。
示例:
export default {
directives: {
focus: {
// 指令的定義
mounted(el) {
el.focus();
},
},
},
};
2.2.2 鉤子函式
自定義指令可以包含以下幾個鉤子函式:
bind
:只呼叫一次,指令第一次繫結到元素時呼叫。inserted
:被繫結元素插入到父節點時呼叫(僅保證父節點存在,但不一定已被插入到文件中)。updated
:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前。指令的值可能發生了改變,也可能沒有。但是你可以透過比較更新前後的值來忽略不必要的模板更新。componentUpdated
:所在元件的 VNode 及其子 VNode 全部更新後呼叫。unbind
:只呼叫一次,指令與元素解綁時呼叫。
示例:
export default {
directives: {
focus: {
bind(el) {
console.log('focus bind');
},
inserted(el) {
console.log('focus inserted');
},
updated(el) {
console.log('focus updated');
},
componentUpdated(el) {
console.log('focus componentUpdated');
},
unbind(el) {
console.log('focus unbind');
},
},
},
};
2.2.3 指令引數與修飾符
自定義指令可以接受一個引數,該引數是一個字串,表示指令的修飾符。修飾符是一個 prefiex,以 .
開頭,用於指明指令應該以特殊方式繫結。
示例:
export default {
directives: {
focus: {
bind(el, binding) {
if (binding.arg === 'input') {
el.focus();
}
},
},
},
};
可以在使用自定義指令時,使用 v-bind
傳遞引數。
示例:
<template>
<input v-focus.input="">
</template>
透過自定義指令,開發者可以擴充套件 Vue 的功能,並在元件中實現更多複雜的DOM操作。
第3章 Vue 3事件處理
3.1 Vue 3事件處理
Vue 3的事件處理機制與Vue 2類似,但使用了更簡潔的語法。Vue 3中不再直接支援v-on
,而是使用@
符號來繫結事件。
3.1.1 基本事件繫結
基礎的事件繫結使用 @
符號,後跟事件名稱,再加事件處理函式。例如:
<button @click="handleClick">點選我</button>
對應的JavaScript部分:
export default {
methods: {
handleClick() {
console.log('Button clicked');
},
},
};
3.1.2 事件修飾符
Vue 3的事件修飾符與Vue 2相容,包括:
.prevent
:阻止事件的預設行為(如阻止表單的預設提交).stop
:阻止事件的進一步傳播(預設行為不會被阻止).capture
:在捕獲階段觸發,從根元素開始向上.self
:僅在事件源和觸發元素相同時觸發.passive
:在觸控移動事件中,用於處理滾動,使事件在預設行為執行前觸發,常用於阻止滾動
例如:
<button @click.prevent="handleClick">阻止預設</button>
3.1.3 按鍵修飾符
.once
:只觸發一次,然後移除事件監聽.key
:用於鍵盤事件,指定一個鍵值(如Enter
、Esc
)來監聽
例如:
<input @keyup.enter="handleEnter" />
在這個例子中,當使用者按下Enter鍵時,handleEnter
方法會被呼叫。
3.2 事件處理函式
在Vue 3中,事件處理函式是響應使用者互動的關鍵部分,它們可以以不同的形式存在,包括內聯事件處理器、方法事件處理器以及結合計算屬性和偵聽器。
3.2.1 內聯事件處理器
內聯事件處理器是指直接在模板中定義的JavaScript表示式,它們通常用於簡單的邏輯。例如:
<button @click="count++">增加計數</button>
在這個例子中,點選按鈕會直接增加count
的值。
3.2.2 方法事件處理器
方法事件處理器是指在Vue元件的methods
選項中定義的函式,這些函式可以處理更復雜的邏輯。例如:
export default {
data() {
return {
count: 0,
};
},
methods: {
incrementCount() {
this.count++;
},
},
};
在模板中使用:
<button @click="incrementCount">增加計數</button>
3.2.3 計算屬性與偵聽器
計算屬性和偵聽器也可以用於事件處理,尤其是在需要根據資料變化來更新檢視或執行某些操作時。
- 計算屬性:計算屬性是基於它們的依賴進行快取的,只有當依賴變化時才會重新計算。例如:
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe',
};
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`;
},
},
};
在模板中使用計算屬性:
<button @click="fullName = 'Jane Smith'">更改全名</button>
- 偵聽器:偵聽器用於觀察和響應Vue例項上的資料變動。例如:
export default {
data() {
return {
message: 'Hello',
};
},
watch: {
message(newVal, oldVal) {
console.log(`Message changed from ${oldVal} to ${newVal}`);
},
},
};
在模板中觸發偵聽器:
<button @click="message = 'Hello, Vue 3'">更改訊息</button>
透過這些不同型別的事件處理函式,Vue 3提供了靈活且強大的工具來處理使用者互動和資料變化。
第4章 高階事件處理
在Vue中,高階事件處理技術包括使用事件匯流排、自定義事件和事件委託,這些技術可以幫助開發者更有效地管理元件間的通訊和事件處理。
4.1 事件匯流排
事件匯流排是一箇中央集線器,用於在非父子關係的元件之間傳遞事件。在Vue 2中,通常使用一個空的Vue例項作為事件匯流排。但在Vue 3中,推薦使用mitt
或tiny-emitter
等第三方庫,因為Vue 3移除了$on
、$off
和$once
等例項方法。
使用事件匯流排的基本步驟如下:
- 建立事件匯流排:
import mitt from 'mitt';
export const emitter = mitt();
- 在傳送元件中觸發事件:
this.emitter.emit('eventName', data);
- 在接收元件中監聽事件:
this.emitter.on('eventName', this.handleEvent);
4.2 自定義事件
自定義事件是Vue中元件間通訊的另一種方式,特別是在父子元件之間。子元件可以使用$emit
方法觸發一個自定義事件,父元件則透過在子元件標籤上使用v-on
或@
來監聽這個事件。
示例:
子元件:
methods: {
handleClick() {
this.$emit('custom-event', '傳遞的資料');
}
}
父元件:
<child-component @custom-event="handleCustomEvent"></child-component>
4.3 事件委託
事件委託是一種最佳化事件處理的技術,它利用事件冒泡機制,將事件處理器新增到父元素上,而不是每個子元素上。這樣可以減少記憶體消耗和提高效能,尤其是在有很多子元素需要監聽相同事件的情況下。
AD:專業搜尋引擎
在Vue中實現事件委託的示例:
<ul @click="handleClick">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
methods: {
handleClick(event) {
const target = event.target;
if (target.tagName === 'LI') {
// 處理點選事件
}
}
}
在這個例子中,handleClick
方法會監聽<ul>
元素上的點選事件,並透過檢查事件目標來確定是否是<li>
元素被點選。這樣,無論有多少個<li>
元素,都只需要一個事件處理器。
第5章 實戰案例
以下是一些Vue.js簡單實戰案例,涵蓋了表單處理、列表渲染與過濾、動態元件與非同步元件的應用。
5.1 表單處理
表單處理是前端應用中常見的需求,Vue提供了簡潔的方法來處理表單輸入。
<template>
<div>
<form @submit.prevent="submitForm">
<input v-model="form.name" placeholder="Name">
<input v-model="form.email" type="email" placeholder="Email">
<button type="submit">Submit</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
email: ''
}
};
},
methods: {
submitForm() {
// 處理表單提交邏輯
console.log('Name:', this.form.name);
console.log('Email:', this.form.email);
}
}
};
</script>
5.2 列表渲染與過濾
列表渲染是Vue中的基礎功能,結合過濾器可以實現複雜的資料展示。
<template>
<div>
<input v-model="search" placeholder="Search">
<ul>
<li v-for="item in filteredList" :key="item.id">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
search: '',
items: [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
// 更多資料...
]
};
},
computed: {
filteredList() {
return this.items.filter(item => item.name.includes(this.search));
}
}
};
</script>
5.3 動態元件與非同步元件
動態元件和非同步元件可以提高應用的靈活性和效能。
<template>
<div>
<button @click="component = 'ChildA'">切換到ChildA</button>
<button @click="component = 'ChildB'">切換到ChildB</button>
<component :is="component"></component>
</div>
</template>
<script>
export default {
data() {
return {
component: 'ChildA'
};
},
components: {
ChildA: { template: '<div>This is ChildA</div>' },
ChildB: { template: '<div>This is ChildB</div>' }
}
};
</script>
非同步元件的實現通常涉及到動態匯入:
components: {
ChildA: () => import('./ChildA.vue'),
ChildB: () => import('./ChildB.vue')
}
這樣,ChildA和ChildB元件會按需載入,從而提高應用的效能。
第6章 最佳實踐
在Vue.js開發中,遵循一些最佳實踐可以提高應用的效能、程式碼的可維護性和可測試性。以下是關於效能最佳化、程式碼組織與重用、測試與除錯的最佳實踐。AD:首頁 | 一個覆蓋廣泛主題工具的高效線上平臺
6.1 效能最佳化
- 使用v-if替代v-show:在需要頻繁切換顯示狀態時,使用
v-if
比v-show
更高效。 - 合理使用計算屬性:對於複雜的資料處理,使用計算屬性可以減少重複計算,提高效能。
- 避免不必要的元件渲染:使用
v-once
指令可以渲染一次後不再更新,適用於靜態內容。 - 非同步元件和程式碼分割:使用非同步元件和Webpack的程式碼分割功能,可以按需載入元件,減少初始載入時間。
- 使用keep-alive快取元件:對於需要頻繁切換但資料不變的元件,使用
<keep-alive>
可以避免重複渲染。
6.2 程式碼組織與重用
- 元件化開發:將UI拆分為可重用的元件,每個元件負責特定的功能。
- 遵循單一職責原則:每個元件或模組應只負責一個功能,提高程式碼的可維護性和可測試性。
- 使用Mixins或Composition API:對於元件間的共享邏輯,可以使用Mixins或Vue 3的Composition API。
- 模組化管理狀態:使用Vuex或其他狀態管理工具來管理應用的狀態,確保狀態的可預測性和可維護性。
- 程式碼風格一致:遵循統一的程式碼風格和命名規範,提高程式碼的可讀性。
6.3 測試與除錯
- 單元測試:為元件和關鍵邏輯編寫單元測試,確保程式碼的正確性。可以使用Jest或Vue Test Utils等工具。
- 端到端測試:使用Cypress或Puppeteer等工具進行端到端測試,確保應用在真實環境中的表現符合預期。
- 使用Vue Devtools:利用Vue Devtools進行除錯,可以直觀地檢視元件樹、狀態和事件。
- 日誌和錯誤處理:在關鍵點新增日誌輸出,便於追蹤問題。使用try-catch處理可能的錯誤,提高應用的健壯性。
- 持續整合:將測試整合到持續整合流程中,確保每次程式碼提交都經過自動化測試。