vue+ts 基礎面試題 (一 )

目錄

1.Vue3 響應式原理

一、?響應式的基本概念

二、 核心機制:Proxy 和依賴追蹤

三、 觸發更新的過程

四、 代碼示例

五、 優勢總結

2.如何實現組件間通信?

一、父子組件通信

1. 父傳子:Props 傳遞

2. 子傳父:自定義事件

二、兄弟組件通信

1. 通過共同父組件中轉

2. 事件總線(Event Bus)

三、跨層級通信

1. Provide/Inject(依賴注入)

2. 全局狀態管理(Vuex/Pinia)

四、特殊場景方案

1.$refs 直接訪問(慎用)

2.$attrs/$listeners(透傳特性)

五、通信方式對比

六、實際案例參考:

3.Composition 的生命周期鉤子

一、主要生命周期鉤子函數

1.onBeforeMount()

2.onMounted()

3.onBeforeUpdate()

4.onUpdated()

5.onBeforeUnmount()

6.onUnmounted()

7.onErrorCaptured()

二、使用注意事項

三、代碼示例

4.Composition API vs Options API

一、Options API(選項式 API)

1. 特點:

2. 示例代碼:

3.優點:

4.缺點:

二、?Composition API(組合式 API)

1. 特點:

2. 示例代碼:

3. 優點:

4. 缺點:

三、核心對比

四、使用場景:

5.setup()?函數作用

一、?核心作用

二、關鍵注意事項

6.ref 和 reactive 的區別

一、基本定義

二、主要區別

三、示例

四、使用場景

7.Props 傳遞機制

一、基本概念

二、?在子組件中聲明 Props

聲明方式:

Options API:

Composition API:

三、在父組件中傳遞 Props

示例:

四、?Props 的類型驗證和默認值

示例:

五、單向數據流原則

六、高級用法

8.自定義事件 (emit)

一、在子組件中定義和觸發事件

二、 在父組件中監聽事件

三、注意事項

9.生命周期鉤子對比

一、生命周期階段與鉤子對照表

二、關鍵變化說明

1.重命名的鉤子

2.Composition API 特性

3.新增調試鉤子

三、執行順序對比(同一組件)

10.watch 和 watchEffect 的區別?

一、 基本概念

二、主要區別

三、示例

四、適用場景總結

1.watch?

2.watchEffect?


1.Vue3 響應式原理

Vue3 的響應式原理是其核心特性之一,它允許數據變化時自動更新視圖。相比 Vue2,Vue3 使用了 JavaScript 的 Proxy 對象來實現更高效和靈活的響應式系統。下面我將逐步解釋其工作機制,幫助你理解整個過程。

一、?響應式的基本概念

  • 響應式系統確保當數據(如變量或對象屬性)發生變化時,依賴該數據的視圖或計算邏輯自動更新。這類似于數學中的函數依賴關系:如果 $y = f(x)$,那么當 $x$ 改變時,$y$ 應自動重新計算。
  • Vue3 的核心是創建一個響應式代理對象,它會攔截對數據的訪問(get)和修改(set)操作,從而追蹤依賴并觸發更新。

二、 核心機制:Proxy 和依賴追蹤

  • Proxy 對象:Vue3 使用 JavaScript 的 Proxy API 來包裝原始數據。Proxy 可以定義“陷阱”(traps),如 getset,用于攔截操作。
    • 當訪問屬性時(如 obj.a),get 陷阱被觸發,系統記錄當前依賴(例如一個渲染函數)。
    • 當修改屬性時(如 obj.a = 1),set 陷阱被觸發,系統通知所有依賴進行更新。
  • 依賴追蹤:Vue3 通過一個全局的“依賴收集器”來管理依賴關系。每個響應式屬性都關聯一個依賴集合(稱為 Dep),當屬性被訪問時,當前運行的“effect”函數(如組件的渲染函數)會被添加到這個集合中。
    • 這可以用一個簡單的數學關系表示:假設有一個響應式對象 $data$,其屬性 $x$ 的依賴集合為 $D_x$。當 $x$ 改變時,系統遍歷 $D_x$ 并執行每個 effect 函數。
    • 公式表示:如果 $effect \in D_x$,那么 $x$ 變化時 $effect()$ 被調用。

三、 觸發更新的過程

  • 當數據被修改時,Proxy 的 set 陷阱會執行以下步驟:
  1. 更新原始數據值。
  2. 通知依賴集合:遍歷所有依賴的 effect 函數,并調用它們。
  3. 如果 effect 函數涉及計算屬性(如 $computed = x + y$),系統會重新計算這些值。
  • 優勢:Proxy 支持深層嵌套對象和數組的響應式,無需像 Vue2 那樣遞歸遍歷整個對象,這提高了性能。

四、 代碼示例

下面是一個簡化版的 Vue3 響應式實現,使用 JavaScript 代碼演示核心邏輯。注意,實際 Vue3 源碼更復雜,但這里聚焦基本原理。

// 創建一個響應式對象
function reactive(target) {return new Proxy(target, {get(obj, key) {track(obj, key); // 追蹤依賴:記錄當前 effect 函數return obj[key];},set(obj, key, value) {obj[key] = value;trigger(obj, key); // 觸發更新:通知所有依賴return true;}});
}// 依賴收集和觸發函數(簡化版)
const depsMap = new Map(); // 存儲每個對象的依賴映射function track(target, key) {let dep = depsMap.get(target);if (!dep) {dep = new Map();depsMap.set(target, dep);}let effects = dep.get(key);if (!effects) {effects = new Set();dep.set(key, effects);}if (currentEffect) {effects.add(currentEffect); // 添加當前 effect 到依賴集合}
}function trigger(target, key) {const dep = depsMap.get(target);if (dep) {const effects = dep.get(key);if (effects) {effects.forEach(effect => effect()); // 執行所有依賴的 effect 函數}}
}// 定義一個 effect 函數(例如組件的渲染邏輯)
let currentEffect = null;
function effect(fn) {currentEffect = fn;fn(); // 首次執行,觸發依賴收集currentEffect = null;
}// 使用示例
const state = reactive({ count: 0 });effect(() => {console.log(`Count is: ${state.count}`); // 依賴 state.count
});state.count = 1; // 輸出:Count is: 1(自動觸發更新)

五、 優勢總結

  • 高效性:Proxy 直接攔截操作,避免了 Vue2 中遞歸定義 getter/setter 的開銷,支持動態添加屬性。
  • 靈活性:可以處理數組索引變化、Map/Set 等復雜數據結構。
  • 可組合性:Vue3 的 reactiveref API 使狀態管理更模塊化。
  • 數學上,這類似于一個動態的依賴圖:每個響應式屬性是一個節點,依賴關系是邊,變化時沿邊傳播更新。

2.如何實現組件間通信?

實現組件間通信是前端開發中的核心問題,不同框架有各自的解決方案。以下是主流的通信方式及代碼示例:

一、父子組件通信

1. 父傳子:Props 傳遞
// 父組件
<Child :message="parentData" />// 子組件
export default {props: ['message'],mounted() {console.log(this.message) // 接收父組件數據}
}
2. 子傳父:自定義事件
// 子組件
this.$emit('child-event', data) // 觸發事件// 父組件
<Child @child-event="handleEvent" />methods: {handleEvent(data) {console.log(data) // 接收子組件數據}
}

二、兄弟組件通信

1. 通過共同父組件中轉
// 父組件
<ChildA @send="receiveData" />
<ChildB :data="sharedData" />data() {return { sharedData: null }
},
methods: {receiveData(data) {this.sharedData = data // 中轉數據}
}
2. 事件總線(Event Bus)
// 創建事件中心
const bus = new Vue()// 組件A(發送)
bus.$emit('update', data)// 組件B(接收)
bus.$on('update', data => {console.log(data)
})

三、跨層級通信

1. Provide/Inject(依賴注入)
// 祖先組件
provide() {return { theme: 'dark' }
}// 后代組件(任意層級)
inject: ['theme'],
mounted() {console.log(this.theme) // 輸出 'dark'
}
2. 全局狀態管理(Vuex/Pinia)
// store.js
export default new Vuex.Store({state: { count: 0 },mutations: {increment(state) {state.count++}}
})// 任意組件
this.$store.commit('increment')
console.log(this.$store.state.count)

四、特殊場景方案

1.$refs 直接訪問(慎用)
<Child ref="childComp" />methods: {callChild() {this.$refs.childComp.childMethod()}
}
2.$attrs/$listeners(透傳特性)
// 父組件
<Child :title="pageTitle" @close="handleClose" />// 中間組件
<Grandchild v-bind="$attrs" v-on="$listeners" />

五、通信方式對比

方式適用場景優點缺點
Props/Events父子組件簡單直接層級深時繁瑣
Event Bus任意組件解耦靈活難以追蹤事件源
Vuex/Pinia中大型應用集中管理,調試工具完善增加項目復雜度
Provide/Inject深層嵌套組件避免逐層傳遞數據非響應式(需處理)

最佳實踐建議

  1. 優先使用 Props/Events 處理父子通信
  2. 跨層級使用 Provide/Inject 替代多級 Props
  3. 復雜應用采用 Vuex/Pinia 管理全局狀態
  4. 避免過度使用 $refs 和事件總線,防止代碼混亂

六、實際案例參考:

// 使用Pinia狀態管理
// store/counter.js
export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),actions: {increment() {this.count++}}
})// 組件A
import { useCounterStore } from '@/store/counter'
const store = useCounterStore()
store.increment() // 組件B
const store = useCounterStore()
console.log(store.count) // 實時獲取最新值

3.Composition 的生命周期鉤子

在 Vue.js 的 Composition API 中,生命周期鉤子提供了一種在組件不同階段(如創建、更新、銷毀)執行自定義邏輯的方式。與 Options API 不同,Composition API 使用函數式鉤子(如 onMountedonUnmounted),這些鉤子需要在 setup() 函數或 <script setup> 語法中導入和使用。下面我將逐步解釋主要鉤子及其用法。

一、主要生命周期鉤子函數

Composition API 提供了以下核心鉤子,每個鉤子對應組件生命周期的特定階段:

1.onBeforeMount()
  • 用途:在組件掛載到 DOM 之前調用。適合執行初始化操作,如設置狀態或獲取數據。
  • 觸發時機:在 setup() 函數運行后,組件首次渲染前。
2.onMounted()
  • 用途:在組件掛載到 DOM 后調用。常用于訪問 DOM 元素、發起 API 請求或設置事件監聽器。
  • 觸發時機:組件首次渲染完成。
3.onBeforeUpdate()
  • 用途:在組件更新之前調用。適合在狀態變化前執行清理或驗證邏輯。
  • 觸發時機:響應式數據變化后,DOM 更新前。
4.onUpdated()
  • 用途:在組件更新后調用。用于處理更新后的 DOM 操作或狀態同步。
  • 觸發時機:DOM 重新渲染完成后。
5.onBeforeUnmount()
  • 用途:在組件卸載之前調用。適合執行清理工作,如移除事件監聽器或取消定時器。
  • 觸發時機:組件銷毀流程開始前。
6.onUnmounted()
  • 用途:在組件卸載后調用。用于最終資源釋放,如斷開網絡連接或清除緩存。
  • 觸發時機:組件從 DOM 中移除后。
7.onErrorCaptured()
  • 用途:捕獲子組件或當前組件的錯誤。用于錯誤處理或日志記錄。
  • 觸發時機:組件樹中任何地方拋出錯誤時。

二、使用注意事項

  • 執行順序:鉤子按生命周期順序執行,例如:onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmounted
  • 依賴導入:所有鉤子需從 vue 包導入,并在 setup() 函數內調用。
  • 異步支持:鉤子回調可以是異步函數,適用于數據獲取等操作。
  • 性能優化:避免在頻繁更新的鉤子(如 onUpdated)中執行重操作,以防止性能問題。

三、代碼示例

以下是一個簡單的 Vue 3 組件示例,展示如何使用 Composition API 的生命周期鉤子:

<template><div>{{ message }}</div>
</template><script>
import { ref, onMounted, onUnmounted } from 'vue';export default {setup() {const message = ref('組件加載中...');// 掛載后更新消息onMounted(() => {message.value = '組件已掛載!';console.log('DOM 已渲染');});// 卸載時清理資源onUnmounted(() => {console.log('組件已卸載');});return { message };}
};
</script>

4.Composition API vs Options API

在 Vue.js 開發中,Composition APIOptions API 是兩種不同的組件代碼組織方式。以下是它們的核心區別和適用場景分析:


一、Options API(選項式 API)

1. 特點
  • 通過預設選項(如 data, methods, computed)組織代碼
  • 邏輯分散在不同選項中,相同功能可能跨多個選項
  • 適合簡單場景,學習曲線平緩
2. 示例代碼
export default {data() {return { count: 0 }},methods: {increment() {this.count++}},computed: {doubleCount() {return this.count * 2}}
}
3.優點
  • 結構清晰直觀,適合新手
  • 選項隔離降低耦合度
  • 兼容性好(Vue 2/3 均支持)
4.缺點
  • 復雜組件中邏輯碎片化
  • 代碼復用依賴 mixins(易命名沖突)

二、?Composition API(組合式 API)

1. 特點
  • 通過 setup() 函數集中管理邏輯
  • 基于函數組合(如 ref, reactive, computed
  • 邏輯按功能聚合,而非選項類型
2. 示例代碼
import { ref, computed } from 'vue'export default {setup() {const count = ref(0)const doubleCount = computed(() => count.value * 2)function increment() {count.value++}return { count, doubleCount, increment }}
}
3. 優點
  • 邏輯高內聚,復雜組件更易維護
  • 更好的 TypeScript 支持
  • 靈活的邏輯復用(自定義 Hook)
  • 代碼更精簡(減少 this 依賴)
4. 缺點
  • 學習曲線較陡峭(需理解響應式原理)
  • 過度集中可能降低可讀性

三、核心對比

維度Options APIComposition API
代碼組織按選項類型分散按功能邏輯集中
邏輯復用Mixins(易沖突)自定義 Hook(解耦性強)
TS 支持有限完整類型推斷
適用場景簡單組件/新手項目復雜邏輯/大型應用
響應式數據通過 data() 返回通過 ref()/reactive() 聲明

四、使用場景:

Options API :項目簡單或團隊 Vue 經驗較少,需要快速迭代原型,維護舊版 Vue 2 項目

Composition API:組件邏輯復雜(如狀態管理、異步流程),需要高度復用邏輯(自定義 Hook),使用 TypeScript 開發,長期維護的大型項目

5.setup()?函數作用

一、?核心作用

  • setup()函數主要用于初始化程序環境,包括設置變量初始值、配置硬件參數、定義畫布大小等。
  • 它只在程序執行時調用一次,之后不再運行

二、關鍵注意事項

  • 執行時機:setup()只在程序啟動時運行一次
  • 必要性:在支持setup()的框架中,它是必須定義的函數(即使為空),否則程序可能報錯
  • 常見錯誤:如果在setup()外部放置初始化代碼,可能導致未定義行為或性能問題

6.refreactive 的區別

一、基本定義

  • ref: 用于創建一個響應式引用,適用于基本類型(如數字、字符串、布爾值)或對象。它返回一個帶有 .value 屬性的對象,訪問或修改數據需要通過 .value
  • reactive: 用于創建一個響應式對象,適用于對象或數組。它直接返回一個代理對象,屬性可以直接訪問和修改,無需額外語法。

二、主要區別

方面refreactive
適用類型更適合基本類型(如 number, string),也可用于對象。僅適用于對象或數組,不適用于基本類型。
訪問方式必須通過 .value 訪問或修改數據(例如 myRef.value)。直接訪問屬性(例如 myReactive.key),無需 .value
模板使用在模板中自動解包,無需寫 .value(Vue 內部處理)。在模板中直接使用屬性名,行為更直觀。
內部實現包裝一個值,使用 Object.defineProperty 或 Proxy 實現響應式。基于 Proxy 代理整個對象,深度監聽嵌套屬性。
解構問題解構后仍保留響應性(因為返回的是引用對象)。解構對象會丟失響應性,需使用 toRefs 輔助函數保持。
重新賦值可以重新賦值整個對象(通過 myRef.value = newValue)。不能直接重新賦值整個對象;需修改屬性或使用 Object.assign

三、示例

import { ref, reactive } from 'vue';// 使用 ref 示例
const countRef = ref(0); // 基本類型
console.log(countRef.value); // 輸出: 0
countRef.value = 10; // 修改值const userRef = ref({ name: 'Alice', age: 30 }); // 對象類型
console.log(userRef.value.name); // 輸出: 'Alice'// 使用 reactive 示例
const userReactive = reactive({ name: 'Bob', age: 25 }); // 對象類型
console.log(userReactive.name); // 輸出: 'Bob',無需 .value
userReactive.age = 26; // 直接修改屬性// 解構問題演示
const { age } = userReactive; // 解構會丟失響應性
// 正確方式:使用 toRefs 保持響應性
const { name, age: reactiveAge } = toRefs(userReactive);

四、使用場景

ref:處理基本類型數據,需要頻繁重新賦值整個對象?

reactive :處理復雜對象或嵌套數據結構,需要直接訪問屬性,避免寫 .value 的模板代碼

總結:

  • reactive 管理狀態對象,用 ref 處理獨立的基本值
  • 選擇時考慮數據結構和代碼可讀性:簡單值用 ref,復雜對象用 reactive

7.Props 傳遞機制

一、基本概念

  • Props 允許父組件將數據“注入”到子組件中,子組件通過聲明 Props 來接收這些數據。
  • 數據流是單向的:父組件更新 Props 會觸發子組件重新渲染,但子組件不能直接修改 Props
  • 用途:適用于配置子組件、傳遞靜態或動態數據,例如傳遞用戶信息、配置選項等。

二、?在子組件中聲明 Props

子組件需要顯式聲明它可以接收的 Props。這通常在組件的選項或 Composition API 中完成。

  • 聲明方式
    • 使用 props 選項(Options API)或 defineProps 宏(Composition API)。
    • 每個 Prop 可以指定類型、默認值和驗證規則。
  • Options API:
    // 子組件 (ChildComponent.vue)
    export default {props: {// 基本類型聲明,例如字符串title: String,// 帶默認值的數字類型count: {type: Number,default: 0},// 必填的布爾類型isActive: {type: Boolean,required: true}}
    }
    
    Composition API:
    // 子組件 (ChildComponent.vue)
    import { defineProps } from 'vue'const props = defineProps({title: String,count: { type: Number, default: 0 },isActive: { type: Boolean, required: true }
    })
    

三、在父組件中傳遞 Props

  • 靜態傳遞:直接傳遞固定值。
  • 動態傳遞:綁定到父組件的數據或計算屬性,實現響應式更新。
示例
<!-- 父組件模板 -->
<template><ChildComponenttitle="歡迎使用 Vue 3"  <!-- 靜態字符串 -->:count="parentCount"     <!-- 動態綁定數字 -->:is-active="isActive"   <!-- 動態綁定布爾值 -->/>
</template><script>
import ChildComponent from './ChildComponent.vue'export default {components: { ChildComponent },data() {return {parentCount: 10,      // 父組件數據isActive: true}}
}
</script>

四、?Props 的類型驗證和默認值

  • 類型:可以指定為原生類型(如 String, Number, Boolean, Array, Object)或自定義類型。
  • 默認值:通過 default 屬性設置,當父組件未傳遞 Prop 時使用。
  • 驗證:使用 validator 函數進行自定義驗證
示例
props: {age: {type: Number,default: 18,validator: (value) => value >= 0  // 驗證年齡非負}
}

五、單向數據流原則

  • Props 是只讀的:子組件不能直接修改接收到的 Prop。如果需要基于 Prop 派生數據,應使用計算屬性。
  • 原因:確保數據源單一,避免父子組件間的循環更新。
    // 子組件中錯誤做法:直接修改 Prop
    // this.count = 20  // 不允許,會觸發警告// 正確做法:使用計算屬性或本地數據
    computed: {doubledCount() {return this.count * 2  // 基于 Prop 派生新值}
    }
    

六、高級用法

  • 傳遞對象或數組:使用 v-bind 傳遞整個對象,子組件通過 Prop 接收。
    <!-- 父組件 -->
    <ChildComponent :user-info="{ name: '張三', age: 30 }" />
    
  • Prop 命名約定:建議使用 camelCase 聲明,但在模板中使用 kebab-case(HTML 屬性不區分大小寫)。例如,聲明為 userInfo,傳遞時用 user-info
  • 響應式更新:父組件數據變化時,子組件的 Prop 會自動更新(得益于 Vue 的響應式系統)。

8.自定義事件 (emit)

一、在子組件中定義和觸發事件

  • 使用 defineEmits 聲明事件列表。
  • 在方法中調用 emit 函數觸發事件,并傳遞數據。
  • 在模板中綁定事件觸發器(如按鈕點擊)。
//子組件 ChildComponent.vue
<script setup>
// 導入 defineEmits
import { defineEmits } from 'vue';// 定義事件列表:聲明一個名為 'customEvent' 的事件
const emit = defineEmits(['customEvent']);// 定義一個方法,在觸發時發送事件
function handleClick() {// 觸發 'customEvent' 事件,并傳遞數據(例如字符串 'Hello from child!')emit('customEvent', 'Hello from child!');
}
</script><template><!-- 在按鈕點擊時調用 handleClick 方法 --><button @click="handleClick">觸發自定義事件</button>
</template>

二、 在父組件中監聽事件

  • 導入子組件。
  • 在模板中使用 @event-namev-on:event-name 監聽事件。
  • 定義一個回調函數來處理事件數據。
//父組件 ParentComponent.vue
<script setup>
// 導入子組件
import ChildComponent from './ChildComponent.vue';// 定義回調函數,接收子組件傳遞的數據
function onCustomEvent(data) {console.log('事件觸發!數據:', data); // 輸出:事件觸發!數據: Hello from child!// 這里可以添加業務邏輯,例如更新父組件狀態
}
</script><template><!-- 監聽子組件的 'customEvent' 事件,并綁定回調函數 --><ChildComponent @customEvent="onCustomEvent" />
</template>

三、注意事項

  • 事件命名規范:推薦使用 kebab-case(短橫線分隔)命名事件,如 custom-event,以保持與 HTML 屬性一致。在模板中監聽時使用 @custom-event,但在 defineEmits 中聲明時使用 camelCase(如 customEvent)。
  • 數據傳遞emit 可以傳遞多個參數,例如 emit('event', arg1, arg2),父組件回調函數接收這些參數。
  • TypeScript 支持:如果使用 TypeScript,可以通過泛型定義事件類型:
    <script setup lang="ts">
    const emit = defineEmits<{(event: 'customEvent', data: string): void;
    }>();
    </script>
    
  • 錯誤處理:確保事件名一致,避免拼寫錯誤。如果父組件未監聽事件,子組件的 emit 不會報錯,但也不會執行任何操作。
  • 替代方案:對于簡單場景,也可以使用 Props 傳遞數據,但自定義事件更適合子組件主動通知父組件的場景。

9.生命周期鉤子對比

Vue 3 的生命周期鉤子在 Options APIComposition API 中有不同實現方式,同時部分鉤子名稱與 Vue 2 有差異。以下是核心對比:

生命周期階段與鉤子對照表

階段Vue 2 (Options)Vue 3 (Options API)Vue 3 (Composition API)
初始化beforeCreatebeforeCreate無(邏輯在 setup() 內)
createdcreated無(邏輯在 setup() 內)
掛載前beforeMountbeforeMountonBeforeMount
掛載完成mountedmountedonMounted
更新前beforeUpdatebeforeUpdateonBeforeUpdate
更新完成updatedupdatedonUpdated
卸載前beforeDestroybeforeUnmountonBeforeUnmount
卸載完成destroyedunmountedonUnmounted
緩存組件activatedactivatedonActivated
deactivateddeactivatedonDeactivated
錯誤捕獲errorCapturederrorCapturedonErrorCaptured
調試鉤子onRenderTracked
onRenderTriggered

關鍵變化說明

1.重命名的鉤子
  1. beforeDestroybeforeUnmount(更準確描述組件卸載行為)
  2. destroyedunmounted(語義更清晰)
2.Composition API 特性
  • 所有鉤子以 onXxx 形式導入(如 onMounted
  • beforeCreatecreatedsetup() 替代:
    import { onMounted } from 'vue';export default {setup() {// 替代 created 邏輯console.log("初始化邏輯");onMounted(() => {console.log("組件已掛載");});}
    }
    
3.新增調試鉤子
  • onRenderTracked:追蹤響應式依賴
  • onRenderTriggered:診斷重新渲染原因

執行順序對比(同一組件)

Options API: beforeCreate → created → beforeMount → mounted → beforeUpdate → updated → beforeUnmount → unmountedComposition API:setup() → onBeforeMount → onMounted → onBeforeUpdate → onUpdated → onBeforeUnmount → onUnmounted

最佳實踐建議

  • 新項目優先使用 Composition API,邏輯更聚合
  • 遷移項目可逐步替換重命名鉤子(如 beforeDestroybeforeUnmount
  • 調試響應式問題時使用 onRenderTracked/onRenderTriggered

10.watchwatchEffect 的區別?

一、 基本概念

  • watch: 用于顯式觀察一個或多個響應式數據源(如 ref、reactive 對象、函數等),并在其變化時執行回調函數。它允許你指定依賴項,并控制監聽行為(如深度監聽或立即執行)。
  • watchEffect: 自動跟蹤其函數體內部的響應式依賴項,并在任何依賴變化時重新運行該函數。它類似于計算屬性(computed),但用于執行副作用(如 DOM 操作、API 調用),而非返回一個值。

二、主要區別

特性watchwatchEffect
依賴項指定方式需要顯式聲明依賴源(如 () => data.value)。自動收集函數體中的所有響應式依賴項。
初始執行行為默認不立即執行回調;可通過 { immediate: true } 選項啟用。在創建時立即執行一次函數體。
訪問舊值/新值回調函數可接收舊值和新值作為參數(如 (newVal, oldVal) => {})。無法直接訪問舊值;只提供當前值。
深度監聽支持支持 { deep: true } 選項進行深度監聽(如對象嵌套屬性)。默認深度監聽所有依賴項,無需額外選項。
適用場景適合精確控制監聽邏輯,如當特定數據變化時觸發操作。適合自動響應依賴變化,如執行副作用或初始化任務。
停止監聽通過返回的停止函數手動停止(如 const stop = watch(...); stop())。同樣通過返回的停止函數手動停止。

三、示例

import { ref, reactive, watch, watchEffect } from 'vue';export default {setup() {const count = ref(0);const user = reactive({ name: 'Alice', age: 25 });// 示例 1: 使用 watchwatch(// 顯式指定依賴源:count 和 user.name[() => count.value, () => user.name],// 回調函數接收新值和舊值([newCount, newName], [oldCount, oldName]) => {console.log('watch - count 變化:', newCount, '舊值:', oldCount);console.log('watch - name 變化:', newName, '舊值:', oldName);},// 選項:立即執行和深度監聽{ immediate: true, deep: true });// 示例 2: 使用 watchEffectwatchEffect(() => {// 自動跟蹤 count.value 和 user.ageconsole.log('watchEffect - count:', count.value);console.log('watchEffect - age:', user.age);// 注意:這里無法訪問舊值});// 修改數據以觸發監聽setTimeout(() => {count.value = 1; // 觸發 watch 和 watchEffectuser.name = 'Bob'; // 觸發 watchuser.age = 26; // 觸發 watchEffect}, 1000);return { count, user };}
};

四、適用場景總結

1.watch?
  • 你需要精確控制監聽哪些數據源。
  • 需要訪問變化前后的值(如比較舊值和新值)。
  • 場景示例:表單驗證(當特定字段變化時檢查)、API 請求(當 ID 變化時重新獲取數據)。
2.watchEffect?
  • 依賴項復雜或動態,希望自動跟蹤所有響應式引用。
  • 需要立即執行副作用(如初始化日志或設置事件監聽器)。
  • 場景示例:實時日志輸出、自動清理資源(結合 onInvalidate 函數)。

如果依賴項明確且需要舊值,用 watch;如果依賴項動態或需要簡化代碼,用 watchEffect

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917663.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917663.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917663.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring AI實戰:SpringBoot項目結合Spring AI開發——提示詞(Prompt)技術與工程實戰詳解

&#x1fa81;&#x1f341; 希望本文能給您帶來幫助&#xff0c;如果有任何問題&#xff0c;歡迎批評指正&#xff01;&#x1f405;&#x1f43e;&#x1f341;&#x1f425; 文章目錄一、前言二、提示詞前置知識2.1 提示詞要素2.2 設計提示詞的通用技巧2.2.1 從簡單開始2.2.…

【后端】Java static 關鍵字詳解

在 Java 中&#xff0c;static 是一個修飾符&#xff0c;用于定義與類相關&#xff08;而非對象實例相關&#xff09;的成員。以下是核心知識點和用法&#xff1a;一、四大用途靜態變量&#xff08;類變量&#xff09; 作用&#xff1a;屬于類&#xff0c;而非實例。所有實例共…

算法訓練營DAY50 第十一章:圖論part01

98. 所有可達路徑 98. 所有可達路徑 【題目描述】 給定一個有 n 個節點的有向無環圖&#xff0c;節點編號從 1 到 n。請編寫一個程序&#xff0c;找出并返回所有從節點 1 到節點 n 的路徑。每條路徑應以節點編號的列表形式表示。 【輸入描述】 第一行包含兩個整數 N&#…

OpenCV:從入門到實戰的全方位指南

目錄 一、OpenCV 簡介 &#xff08;一&#xff09;特點 &#xff08;二&#xff09;應用場景 二、OpenCV 的核心模塊 &#xff08;一&#xff09;core 模塊 &#xff08;二&#xff09;imgproc 模塊 &#xff08;三&#xff09;video 模塊 &#xff08;四&#xff09;f…

如何在 Ubuntu 24.04 上安裝和配置 TFTP 服務器

了解如何在 Ubuntu 24.04 Linux 上安裝 TFTP 以執行基本的文件傳輸。 簡單文件傳輸協議(TFTP)是標準 FTP 的輕量級替代方案,用于在聯網設備之間傳輸文件。與 FTP 和 HTTP 相比,TFTP 更簡單,無需復雜的客戶端-服務器模型即可操作。這就是為什么該協議用于執行基本文件傳輸…

基于 AXI-Lite 實現可擴展的硬件函數 RPC 框架(附完整源碼)

AXI-Lite 實現RPC調用硬件函數服務 &#x1f44b; 本文介紹如何基于 AXI-Lite 總線設計一個通用的“硬件函數調用框架”。主機端&#xff08;PS&#xff09;只需通過寄存器寫入參數與啟動標志&#xff0c;即可觸發 PL 模塊執行指定算法邏輯&#xff0c;并將結果返回。 該機制本…

[spring-cloud: NamedContextFactory ClientFactoryObjectProvider]-源碼閱讀

依賴 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-commons</artifactId><version>4.3.0</version> </dependency>源碼 NamedContextFactory NamedContextFactory 類通過創建多個子…

HBase MOB技術特點及使用場景介紹

在 HBase 2.0 版本之前,雖然 HBase 能夠存儲從 1 字節到 10MB 大小的二進制對象 ,但其讀寫路徑主要針對小于 100KB 的值進行了優化。當面對大量大小在 100KB - 10MB 之間的數據時,傳統的存儲方式就會暴露出問題。例如,當存儲大量的圖片、文檔或短視頻等中等大小對象時,由于…

Ubuntu 配置密鑰+密碼登錄

目錄 1、密鑰生成 2、發送公鑰至 需要連接的服務器 3、選用私鑰登錄 1、密鑰生成 ssh-keygen -t rsa -b 4096 -C "angindem"2、發送公鑰至 需要連接的服務器 將.ssh中的id_rsa.pub 的密鑰&#xff0c;放在authorized_keys中 注意&#xff1a;.ssh 文件夾一定賦予…

谷歌瀏覽器Chrome 緩存遷移

步驟 1&#xff1a;準備數據遷移1. 關閉 Chrome 及所有后臺進程在任務管理器&#xff08;CtrlShiftEsc&#xff09;中結束所有 chrome.exe 進程。 2. 備份并移動原數據- 將 C:\Users\xxx\AppData\Local\Google\Chrome\User Data **整個文件夾**復制到新位置&#xff08;如 G:\…

Java中的RabbitMQ完全指南

Java中的RabbitMQ完全指南 1. 引言 什么是RabbitMQ RabbitMQ是一個開源的消息代理和隊列服務器&#xff0c;實現了高級消息隊列協議&#xff08;AMQP&#xff09;。它充當應用程序之間的消息中間件&#xff0c;允許分布式系統中的不同組件進行異步通信。RabbitMQ使用Erlang語言…

【MCAL】AUTOSAR架構下SPI數據異步DMA收發具體實現

目錄 前言 正文 1.依賴的硬件特性 1.1.SPI硬件特性 1.1.1. TXFIFO Single Move Mode 1.1.2. RXFIFO Single Move Mode 1.1.3. Move Counter模式 1.1.4. PT中斷 1.2.IR硬件特性 1.3.DMA硬件特性 1.3.1. DMA通道硬件請求 1.3.2. DMA循環Buffer 1.3.3. DMA Link List …

【Unity】協程 Async

協程 協程是 Unity 內置的異步機制&#xff0c;通過 yield 暫停執行&#xff0c;實現任務在多幀中分段執行。與普通函數不同&#xff0c;協程可在執行過程中掛起和恢復&#xff0c;呈現"并發"效果&#xff0c;但本質上仍運行于主線程。若在協程中進行耗時操作&#…

《揭秘!10 分鐘洞悉 Prompt、Function Calling、MCP 與 AI agent 奧秘》

Prompt、Function Calling、MCP、AI agent這些術語頻繁闖入我們的視野&#xff0c;它們到底都是什么、有啥關系。只需十分鐘&#xff0c;咱們抽絲剝繭&#xff0c;揭開它們的神秘面紗&#xff0c;輕松掌握這些關鍵概念 并了解AI agent 完整執行流程。 一、提示詞&#xff08;P…

決策樹(回歸樹)全解析:原理、實踐與應用

文章目錄一、概述1.1 介紹1.2 回歸樹和分類樹區別二、重要參數、屬性及接口2.1 criterion&#xff08;不純度衡量指標&#xff09;2.2 回歸樹如何工作&#xff08;核心流程拆解&#xff09;三、用回歸樹擬合正弦曲線&#xff08;實戰案例&#xff09;3.1 繪制正弦曲線3.2 為正弦…

【盤古100Pro+開發板實驗例程】FPGA學習 | HDMI 回環實驗

本原創文章由深圳市小眼睛科技有限公司創作&#xff0c;版權歸本公司所有&#xff0c;如需轉載&#xff0c;需授權并注明出處&#xff08;www.meyesemi.com) 1. 實驗簡介 實驗目的&#xff1a; 完成 HDMI 回環實驗 實驗環境&#xff1a; Window11 PDS2022.2-SP6.4 硬件環境…

鴻蒙系統PC安裝指南

鴻蒙系統PC安裝指南一、安裝DevEco Studio集成開發環境二、下載鴻蒙系統PC三、啟動鴻蒙系統及使用一、安裝DevEco Studio集成開發環境首先訪問華為官網上&#xff0c;注冊并登錄華為賬號&#xff0c;以開始下載所需的軟件。若尚未注冊&#xff0c;請先注冊一個。在官網頁面中&a…

三十九、【擴展工具篇】Allpairspy 組合用例生成器:智能設計高效測試集

三十九、【擴展工具篇】Allpairspy 組合用例生成器:智能設計高效測試集 前言 準備工作 第一部分:后端實現 - `allpairspy` API 1. 創建 `allpairspy` 服務 2. 創建 `allpairspy` API 視圖 3. 注冊 API 路由 第二部分:前端實現 - `Allpairspy` 工具界面 1. 創建 API 服務 (`s…

ZooKeeper 深度實踐:從原理到 Spring Boot 全棧落地

在 Kubernetes 為主流注冊發現的今天&#xff0c;給出如何在 Spring Boot 中基于 ZooKeeper 實現服務注冊/發現、分布式鎖、配置中心以及集群協調的完整代碼與最佳實踐。所有示例均可直接復制運行。 1. ZooKeeper 架構與核心原理 1.1 角色 Leader&#xff1a;處理寫請求&…

可驗證隨機函數-VRF

可驗證隨機函數&#xff08;Verifiable Random Function, VRF&#xff09;是一種結合密碼學技術的偽隨機數生成器&#xff0c;其核心特點是生成的隨機數可被公開驗證&#xff0c;且具有不可預測性和唯一性。以下是VRF的詳細解析&#xff1a;1. 基本定義與核心特性 可驗證性&…