對 Vue Hook 的理解和簡單案例
1. Vue Hook 的理解
Vue Hook 是在 Vue 3 中引入的一種新的代碼組織和狀態管理方式,它受到了 React Hook 的啟發。Vue Hook 主要通過組合式 API (Composition API) 來實現,讓開發者能夠更靈活、更高效地管理組件邏輯和狀態。
2. Vue Hook 的優勢
1. 更好的邏輯復用
在選項式 API (Options API) 中,邏輯復用通常依賴于 mixins 和高階組件 (HOC)。但是,mixins 存在命名沖突和代碼難以追蹤的問題,而高階組件則可能導致組件層級過深。Vue Hook 通過組合函數 (Composable) 提供了一種更簡潔和直觀的方式來復用邏輯。
2. 更好的代碼組織
組合式 API 允許開發者在同一地方聲明和使用狀態、計算屬性、方法等,避免了選項式 API 中將相關邏輯分散在多個選項中的情況。這使得代碼更具可讀性和可維護性。
3. 更靈活的響應式系統
Vue 3 引入了新的響應式系統,它基于 Proxy 實現,相較于 Vue 2 的基于 Object.defineProperty 的實現,性能更好,功能更強大。組合式 API 可以更方便地使用這些新的響應式功能。
3. Vue Hook 的核心概念
1. ref 和 reactive
ref用于定義基本類型的響應式數據,它會返回一個帶有.value屬性的對象。reactive用于定義對象類型的響應式數據,它返回一個深度響應的對象。
2. 組合函數 (Composable)
組合函數是復用邏輯的核心。它是一個普通的 JavaScript 函數,可以接收參數,并返回響應式數據或其他組合函數的結果。
3. 生命周期鉤子
組合式 API 提供了與選項式 API 中生命周期鉤子類似的函數,如 onMounted、onUpdated 和 onUnmounted,用于在組件的不同生命周期階段執行特定邏輯。
簡單案例:入門 Vue Hook
示例:計數器組件
以下是一個簡單的計數器組件,展示了如何使用組合式 API 和 Vue Hook 來管理組件狀態和邏輯。
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
// 定義一個 ref 響應式數據
const count = ref(0);
// 定義一個方法來更新 count
const increment = () => {
count.value++;
};
</script>
詳細解釋
-
定義響應式數據
-
使用
ref定義一個響應式數據count,初始值為 0。ref返回一個對象,這個對象的.value屬性是響應式的。
const count = ref(0);
2.定義更新函數
const increment = () => { count.value++; };
-
定義一個函數
increment,每次調用時將count.value加 1。因為count是響應式的,當count.value發生變化時,視圖會自動更新。 -
3.在模板中使用
-
<p>Count: {{ count }}</p> <button @click="increment">Increment</button>
在模板中直接使用count來顯示計數值,并在按鈕的click事件中綁定increment函數。
進階案例:Todo 列表
<template>
<div>
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a todo" />
<ul>
<li v-for="(todo, index) in todos" :key="index">
<input type="checkbox" v-model="todo.completed" />
<span :class="{ done: todo.completed }">{{ todo.text }}</span>
<button @click="removeTodo(index)">Remove</button>
</li>
</ul>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
const newTodo = ref('');
const todos = reactive([]);
// 組合函數
const useTodos = () => {
const addTodo = () => {
if (newTodo.value.trim()) {
todos.push({ text: newTodo.value.trim(), completed: false });
newTodo.value = '';
}
};
const removeTodo = (index) => {
todos.splice(index, 1);
};
return { newTodo, todos, addTodo, removeTodo };
};
const { newTodo, todos, addTodo, removeTodo } = useTodos();
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
詳細解釋
-
定義響應式數據
-
使用
ref和reactive定義響應式數據newTodo和todos。newTodo是一個字符串,用于存儲新待辦事項的文本;todos是一個數組,用于存儲待辦事項列表。 -
const newTodo = ref(''); const todos = reactive([]);
-
2.定義組合函數
const useTodos = () => { const addTodo = () => { if (newTodo.value.trim()) { todos.push({ text: newTodo.value.trim(), completed: false }); newTodo.value = ''; } }; const removeTodo = (index) => { todos.splice(index, 1); }; return { newTodo, todos, addTodo, removeTodo }; }; const { newTodo, todos, addTodo, removeTodo } = useTodos();
-
定義一個組合函數
useTodos,它包含添加和移除待辦事項的邏輯。useTodos返回newTodo、todos、addTodo和removeTodo,以便在組件中使用。 -
3.在模板中使用
-
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a todo" /> <ul> <li v-for="(todo, index) in todos" :key="index"> <input type="checkbox" v-model="todo.completed" /> <span :class="{ done: todo.completed }">{{ todo.text }}</span> <button @click="removeTodo(index)">Remove</button> </li> </ul>
在模板中使用 v-model 雙向綁定 newTodo,并綁定 keyup.enter 事件到 addTodo 函數。在 v-for 循環中渲染 todos 列表,并為每個待辦事項添加復選框和移除按鈕。

浙公網安備 33010602011771號