深入理解Vue3組合式API的實(shí)現(xiàn)
組合式API的好處
1.更好的邏輯組織:
在選項(xiàng)式API中,組件邏輯是按照data、methods、computed、watch等分塊寫的,這種分離可能會(huì)導(dǎo)致相同功能的代碼分散在不同的部分。
組合式API 通過將相關(guān)的邏輯組合在一起,使代碼更加緊湊和清晰,尤其實(shí)在復(fù)雜組件中,組織代碼的方式更加自然。
2.更好的邏輯復(fù)用:
在選項(xiàng)式API中,如果要復(fù)用邏輯,通常使用mixin,但mixin存在作用域不清晰、命名沖突等問題。
組合式API提供了composable (可組合函數(shù))的概念,運(yùn)行將邏輯抽取成獨(dú)立的函數(shù),這樣復(fù)用性更強(qiáng)、代碼更清晰。
3.更好的類型推斷支持:
組合式API更好地支持TypeScript,尤其是在函數(shù)內(nèi)部可以更明確地推斷出數(shù)據(jù)和函數(shù)的類型,而不需要額外的類型定義。
4.更靈活的響應(yīng)式系統(tǒng):
組合式API 提供了更靈活的響應(yīng)式系統(tǒng),比如通過ref和reactive可以更直觀地控制響應(yīng)式數(shù)據(jù)的行為。
Vue3有哪些生命周期?
- setup():開始創(chuàng)建組件,在beforeCreate 和 created 之前進(jìn)行, 創(chuàng)建的是 data 和 method
- onBeforeMount():組件掛載到節(jié)點(diǎn)上之前執(zhí)行的函數(shù)
- onMounted():組件掛在完成后執(zhí)行的函數(shù);
- onBeforeUpdate():組件更新之前執(zhí)行的函數(shù);
- onUpdated():組件更新完成之后執(zhí)行的函數(shù);
- onBeforeUnmount():組件卸載之前執(zhí)行的函數(shù);
- onUnmounted():組件卸載完成后執(zhí)行的函數(shù);
- onActived():被包含在<keep-alive>中的組件, 會(huì)多出兩個(gè)生命周期鉤子函數(shù),被激活時(shí)執(zhí)行;
- onDeactivated():比如 A 組件切換到 B 組件,A組件消失時(shí)執(zhí)行;
- onErrorCaptured():當(dāng)捕獲一個(gè)來自子孫組件的異常時(shí)激活鉤子函數(shù)。
Vue2.X 和 Vue3.X對(duì)比
vue2 -------> vue3 beforeCreate --------> setup(()=>{}) created --------> setup(()=>{}) beforeMount --------> onBeforeMount(()=>{}) mounted --------> onMounted(()=>{}) beforeUpdate --------> onBeforeUpdate(()=>{}) updated --------> onUpdated(()=>{}) beforeDestroy --------> onBeforeUnmount(()=>{}) destroyed --------> onUnmounted(()=>{}) activated --------> onActivated(()=>{}) deactivated --------> onDeactivated(()=>{}) errorCaptured --------> onErrorCaptured(()=>{})
watch 和 watchEffect 的區(qū)別?
1.watch
watch用于監(jiān)聽特定響應(yīng)式數(shù)據(jù)的變化,并在數(shù)據(jù)變化時(shí)執(zhí)行回調(diào)函數(shù)。下面是一個(gè)使用watch的例子:
import { ref, watch } from 'vue'; const count = ref(0); watch(count, (newValue, oldValue) => { console.log(`Count changed from ${oldValue} to ${newValue}`); // 執(zhí)行一些副作用操作,例如發(fā)送API請(qǐng)求、更新其他狀態(tài)等 }); // 改變count值會(huì)觸發(fā)watch的回調(diào) count.value++;
- watch接受兩個(gè)參數(shù), 第一個(gè)參數(shù)是要監(jiān)聽的響應(yīng)式值或計(jì)算屬性(可以是ref、reactive對(duì)象的屬性或者是computed的結(jié)果),第二個(gè)參數(shù)是回調(diào)函數(shù)。
- 回調(diào)函數(shù)會(huì)在監(jiān)聽的值發(fā)生變化時(shí)被調(diào)用,它會(huì)接收到新的值和舊的值作為參數(shù)。
- 如果你要深度監(jiān)聽對(duì)象或數(shù)組的變化, 可以為watch添加第三個(gè)參數(shù),配置對(duì)象,如{deep:true}
2.watchEffect
watchEffect則是立即執(zhí)行并且持續(xù)監(jiān)聽其內(nèi)部依賴變化的函數(shù)。每當(dāng)其依賴的響應(yīng)式值發(fā)生變化時(shí),它都會(huì)重新執(zhí)行。
import { ref, watchEffect } from 'vue'; const count = ref(0); const message = ref('Initial Message'); watchEffect(() => { console.log(`Count is ${count.value}, and message is ${message.value}`); // 根據(jù)count和message的值執(zhí)行一些副作用操作 }); // 改變count或message值都會(huì)觸發(fā)watchEffect的再次執(zhí)行 count.value++; message.value = 'Updated Message';
詳細(xì)講解:
- watchEffect不需要指定監(jiān)聽的具體值,它會(huì)自動(dòng)追蹤其內(nèi)部表達(dá)式所涉及的所有響應(yīng)式依賴。
- 當(dāng)調(diào)用watchEffect時(shí),它會(huì)立即執(zhí)行一次,并記錄下內(nèi)部依賴的快照,此后每當(dāng)依賴項(xiàng)變化時(shí),它會(huì)再次執(zhí)行。
- 若想停止監(jiān)聽,可以返回一個(gè)清理函數(shù),例如在組件卸載時(shí)清理副作用。
watch和watchEffect的對(duì)比
watch
- watch顯式指定依賴數(shù)據(jù),依賴數(shù)據(jù)更新時(shí)執(zhí)行回調(diào)函數(shù)
- 具有一定的惰性lazy 第一次頁面展示的時(shí)候不會(huì)執(zhí)行,只有數(shù)據(jù)變化的時(shí)候才會(huì)執(zhí)行(設(shè)置immediate: true時(shí)可以變?yōu)榉嵌栊裕撁媸状渭虞d就會(huì)執(zhí)行)
- 監(jiān)視r(shí)ef定義的響應(yīng)式數(shù)據(jù)時(shí)可以獲取到原值
- 既要指明監(jiān)視的屬性,也要指明監(jiān)視的回調(diào)
watchEffect
- watchEffect自動(dòng)收集依賴數(shù)據(jù),依賴數(shù)據(jù)更新時(shí)重新執(zhí)行自身
- 立即執(zhí)行,沒有惰性,頁面的首次加載就會(huì)執(zhí)行
- 無法獲取到原值,只能得到變化后的值
- 不用指明監(jiān)視哪個(gè)屬性,監(jiān)視的回調(diào)中用到哪個(gè)屬性就監(jiān)視哪個(gè)屬性
ref 與 reactive 的區(qū)別?
定義
reactive 和 ref 是 Vue 3 中的兩種響應(yīng)式數(shù)據(jù)綁定方式,ref 適用于簡(jiǎn)單的響應(yīng)式數(shù)據(jù),而 reactive 則適用于復(fù)雜對(duì)象或數(shù)組的響應(yīng)式數(shù)據(jù)。
ref:用于聲明 基本類型 或者單個(gè)變量的響應(yīng)式數(shù)據(jù)。
ref 的核心在于它包裝了一個(gè)值,當(dāng)這個(gè)值變化時(shí),依賴它的視圖會(huì)重新渲染。
注意:ref 返回的是一個(gè)對(duì)象,其中的值通過 .value 屬性訪問。
const count = ref(0); console.log(count.value); // 0 count.value++;
reactive:用于聲明 對(duì)象 或 數(shù)組 的響應(yīng)式數(shù)據(jù)。
reactive 更適合處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)(對(duì)象或數(shù)組)。它返回的是一個(gè)響應(yīng)式對(duì)象,直接操作對(duì)象的屬性時(shí),視圖會(huì)自動(dòng)更新。
const state = reactive({ name: 'Vue', age: 3 }); console.log(state.name); // 'Vue' state.age = 4; // 視圖會(huì)自動(dòng)更新
主要區(qū)別如下:
1. 數(shù)據(jù)類型不同:
ref用于包裝JavaScript基本類型的數(shù)據(jù)(如字符串、數(shù)字、布爾值等),
而reactive可以用于包裝JavaScript對(duì)象和數(shù)組等復(fù)雜類型的數(shù)據(jù)。
2. 使用方式不同:
ref需要通過在模板中使用ref指令以及在JavaScript代碼中使用ref函數(shù)進(jìn)行創(chuàng)建和使用,而reactive則需要通過調(diào)用Vue.js提供的reactive函數(shù)進(jìn)行包裝和創(chuàng)建。
3. 訪問方式不同:
對(duì)于通過ref函數(shù)創(chuàng)建的響應(yīng)式數(shù)據(jù),我們可以通過.value屬性來訪問其實(shí)際值;而對(duì)于通過reactive函數(shù)創(chuàng)建的響應(yīng)式對(duì)象,我們可以直接訪問其屬性或調(diào)用其方法。
4. 設(shè)計(jì)理念不同:
ref主要是為了解決單一元素/數(shù)據(jù)的響應(yīng)式問題,而reactive則是為了解決JavaScript對(duì)象和數(shù)組等復(fù)雜數(shù)據(jù)結(jié)構(gòu)的響應(yīng)式問題
<script setup>
<script setup>
是 Vue 3 引入的一種新語法糖,它用于使用組合式 API 編寫組件。這種語法簡(jiǎn)化了 Composition API 的使用,使得編寫和組織組件邏輯更加簡(jiǎn)潔和直觀。
主要特點(diǎn)
- 聲明式:
<script setup>
提供了一種聲明式的方式來使用組合式 API,減少了樣板代碼。 - 自動(dòng)響應(yīng):在
<script setup>
中定義的響應(yīng)式引用(如ref
和reactive
)和函數(shù)自動(dòng)暴露給模板,無需返回對(duì)象。 - 生命周期鉤子:生命周期鉤子(如
onMounted
、onUpdated
等)可以直接導(dǎo)入和使用,無需定義匿名函數(shù)。 - 模塊作用域:在
<script setup>
中導(dǎo)入的變量和函數(shù)自動(dòng)擁有模塊作用域,減少了全局命名沖突。
基本用法
<script setup> import { ref, computed, onMounted } from 'vue'; const count = ref(0); const doubledCount = computed(() => count.value * 2); onMounted(() => { console.log('Component is mounted'); }); function increment() { count.value++; } </script> <template> <div> <p>Count: {{ count }}</p> <p>Doubled Count: {{ doubledCount }}</p> <button @click="increment">Increment</button> </div> </template>
與 <script> 的區(qū)別
- 無需返回對(duì)象:在
<script setup>
中,你不需要返回一個(gè)對(duì)象來暴露響應(yīng)式狀態(tài)、計(jì)算屬性和方法給模板。 - 更少的代碼:
<script setup>
使得組件的編寫更加簡(jiǎn)潔,減少了樣板代碼。
組件定義
在 <script setup>
中,你可以定義組件的響應(yīng)式狀態(tài)、計(jì)算屬性、方法和生命周期鉤子,就像在 <script>
標(biāo)簽中使用組合式 API 一樣,但是更加簡(jiǎn)潔。
生命周期鉤子
<script setup> import { onMounted } from 'vue'; onMounted(() => { console.log('Component is mounted'); }); </script>
到此這篇關(guān)于深入理解Vue3組合式API的文章就介紹到這了,更多相關(guān)Vue3組合式API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue路由守衛(wèi)+登錄態(tài)管理實(shí)例分析
這篇文章主要介紹了vue路由守衛(wèi)+登錄態(tài)管理,結(jié)合實(shí)例形式分析了vue路由守衛(wèi)與登錄態(tài)管理相關(guān)操作步驟與實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-05-05Vue-router 中hash模式和history模式的區(qū)別
這篇文章主要介紹了Vue-router 中hash模式和history模式的區(qū)別,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07vue結(jié)合Echarts實(shí)現(xiàn)點(diǎn)擊高亮效果的示例
下面小編就為大家分享一篇vue結(jié)合Echarts實(shí)現(xiàn)點(diǎn)擊高亮效果的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03淺談el-table中使用虛擬列表對(duì)對(duì)表格進(jìn)行優(yōu)化
我們會(huì)經(jīng)常使用表格,如果數(shù)據(jù)量大就直接可以分頁,如果多條可能會(huì)影響表格的卡頓,那么應(yīng)該如何進(jìn)行優(yōu)化,感興趣的可以了解一下2021-08-08Vue+ElementUi實(shí)現(xiàn)點(diǎn)擊表格鏈接頁面跳轉(zhuǎn)和路由效果
這篇文章主要介紹了Vue+ElementUi實(shí)現(xiàn)點(diǎn)擊表格中鏈接進(jìn)行頁面跳轉(zhuǎn)和路由,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-03-03Vue3中按需引入ECharts詳細(xì)步驟(一看就會(huì))
新項(xiàng)目采用Vue3作為前端項(xiàng)目框架,避免不了要使用echarts,這篇文章主要給大家介紹了關(guān)于Vue3中按需引入ECharts的相關(guān)資料,需要的朋友可以參考下2023-09-09Vue 簡(jiǎn)單實(shí)現(xiàn)前端權(quán)限控制的示例
這篇文章主要介紹了Vue 簡(jiǎn)單實(shí)現(xiàn)前端權(quán)限控制的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12