注:純手打,如有錯誤歡迎評論區交流!
轉載請注明出處:https://blog.csdn.net/testleaf/article/details/148056625
編寫此文是為了更好地學習前端知識,如果損害了有關人的利益,請聯系刪除!
本文章將不定時更新,敬請期待!!!
歡迎點贊、收藏、轉發、關注,多謝!!!
目錄
- 一、Vue2選項式API和Vue3組合式API
- 二、Vue3相比于Vue2的優勢
- 三、使用create-vue搭建Vue3項目
- 四、組合式API - setup選項
- 五、組合式API - reactive和ref函數
- 六、組合式API - computed
- 七、組合式API - watch
- 八、組合式API - 生命周期函數
一、Vue2選項式API和Vue3組合式API
1、Vue 2 選項式 API(Options API)?
<template><div><p>{{ message }}</p><button @click="reverseMessage">Reverse</button></div>
</template><script>
export default {data() {return { message: "Hello Vue 2!" };},methods: {reverseMessage() {this.message = this.message.split('').reverse().join('');}},mounted() {console.log("Component mounted!");}
};
</script>
2、Vue 3 組合式 API(Composition API)
<template><div><p>{{ message }}</p><button @click="reverseMessage">Reverse</button></div>
</template><script>
import { ref, onMounted } from 'vue';export default {setup() {const message = ref("Hello Vue 3!");const reverseMessage = () => {message.value = message.value.split('').reverse().join('');};onMounted(() => {console.log("Component mounted!");});return { message, reverseMessage };}
};
</script>
3、核心對比
??對比維度?? | ??Vue 2 選項式 API?? | ??Vue 3 組合式 API?? |
---|---|---|
????代碼組織方式?? | ??按選項(data 、methods 等)分類 | ??按邏輯功能聚合(setup() 函數內) |
????邏輯復用?? | ??依賴 mixins (易沖突) | ??自定義組合函數(無沖突) |
????TypeScript 支持?? | ?? 較弱(this 類型推斷困難) | ??優秀(ref、reactive 類型明確) |
????適用場景 | ???? 簡單組件、小型項目 | ??復雜組件、大型項目、邏輯復用需求 |
????響應式系統?? | ??基于 Object.defineProperty (Vue 2) | ?? 基于 Proxy (Vue 3,性能更好) |
二、Vue3相比于Vue2的優勢
1、更容易維護:組合式API、更好的TypeScript
支持;
2、更快的速度:重寫diff
算法、模板編譯優化、更高效的組件初始化;
3、更優的數據響應式:Proxy
;
4、更小的體積:良好的TreeShaking
、按需引入;
三、使用create-vue搭建Vue3項目
1、認識create-vue
create-vue
是Vue官方新的腳手架工具,底層切換到了 vite
(下一代前端工具鏈),為開發提供極速響應。
而vue-cli
的底層是webpack
。
2、使用create-vue
創建項目
npm init vue@latest
3、項目關鍵文件
vite.config.js
- 項目的配置文件:基于vite
的配置package.json
- 項目包文件:核心依賴項變成了Vue3.x
和vite
main.js
- 入口文件:createApp
函數創建應用實例app.vue
- 根組件:SFC
單文件組件script - template - style
- 變化一:腳本
script
和模板template
順序調整 - 變化二:模板
template
不再要求唯一根元素 - 變化三:腳本
script
添加setup
標識支持組合式API
- 變化一:腳本
index.html
- 單頁入口:提供id
為app
的掛載點
四、組合式API - setup選項
1、寫法
<script>export default {setup(){},beforeCreate(){}}
</script>
2、執行時機
在beforeCreate
鉤子之前執行;
3、setup
中寫代碼的特點
在setup
函數中寫的數據和方法需要在末尾以對象的方式return
,才能給模版使用;
4、<script setup>
語法糖
script標簽添加 setup標記,不需要再寫導出語句,默認會添加導出語句;
<script setup>const message = 'this is message'const logMessage = ()=>{console.log(message)}
</script>
五、組合式API - reactive和ref函數
1、reactive
接受對象類型數據的參數傳入并返回一個響應式的對象;
import { reactive } from 'vue'const state = reactive({count: 0,message: 'Hello Vue!'
})// 訪問和修改
state.count++
console.log(state.message)
2、ref
接收簡單類型或者對象類型的數據傳入并返回一個響應式的對象;
import { ref } from 'vue'const count = ref(0)
const message = ref('Hello Vue!')// 訪問和修改
count.value++ // 注意需要通過.value訪問
console.log(message.value)
3、比較與選擇
特性 | reactive | ref |
---|---|---|
適用類型 | 對象 | 任意值 |
訪問方式 | 直接訪問 | .value |
模板中使用 | 直接使用 | 自動解包 |
解構響應性 | 丟失 | 保持 |
4、使用建議
- 當需要管理一組相關狀態時,使用
reactive
- 當需要管理單個原始值時,使用
ref
- 在組合式函數中返回狀態時,通常使用
ref
以保持靈活性
六、組合式API - computed
計算屬性基本思想和Vue2保持一致,組合式API下的計算屬性只是修改了API寫法;
基本用法:
import { ref, computed } from 'vue'const count = ref(0)// 創建一個計算屬性
const doubleCount = computed(() => count.value * 2)console.log(doubleCount.value) // 0
count.value++
console.log(doubleCount.value) // 2
可寫計算屬性:
const firstName = ref('John')
const lastName = ref('Doe')const fullName = computed({get() {return `${firstName.value} ${lastName.value}`},set(newValue) {[firstName.value, lastName.value] = newValue.split(' ')}
})fullName.value = 'Jane Smith' // 會自動更新firstName和lastName
七、組合式API - watch
1、基本用法
import { ref, watch } from 'vue'const count = ref(0)// 基本watch用法
watch(count, (newValue, oldValue) => {console.log(`count從${oldValue}變為${newValue}`)
})
2、觀察多個源
const firstName = ref('')
const lastName = ref('')// 觀察多個ref
watch([firstName, lastName], ([newFirst, newLast], [oldFirst, oldLast]) => {console.log(`名字從${oldFirst} ${oldLast}變為${newFirst} ${newLast}`)
})
3、觀察響應式對象
const state = reactive({user: {name: 'Alice',age: 25}
})// 深度觀察對象
watch(() => state.user,(newUser, oldUser) => {console.log('用戶信息變化:', newUser)},{ deep: true }
)
4、立即執行
const data = ref(null)// 立即執行回調
watch(data,(newValue) => {console.log('數據:', newValue)},{ immediate: true }
)
5、觀察getter函數
const state = reactive({items: [],total: 0
})// 觀察計算值
watch(() => state.items.length,(newLength) => {console.log(`項目數量變為: ${newLength}`)}
)
6、停止觀察
const stop = watch(count, (newValue) => {if (newValue > 10) {stop() // 停止觀察console.log('已達到最大值,停止觀察')}
})
7、實際應用示例
<template><div><input v-model="searchQuery" placeholder="搜索..."><div v-if="isSearching">搜索中...</div><ul v-else><li v-for="result in searchResults" :key="result.id">{{ result.name }}</li></ul></div>
</template><script setup>
import { ref, watch } from 'vue'const searchQuery = ref('')
const searchResults = ref([])
const isSearching = ref(false)// 防抖搜索
watch(searchQuery, async (newQuery) => {if (!newQuery.trim()) {searchResults.value = []return}isSearching.value = truetry {// 模擬API調用await new Promise(resolve => setTimeout(resolve, 300))searchResults.value = await mockSearch(newQuery)} finally {isSearching.value = false}
})async function mockSearch(query) {// 模擬API返回return [{ id: 1, name: `${query} 結果1` },{ id: 2, name: `${query} 結果2` }]
}
</script>
8、watchEffect
與watch相關的還有watchEffect,它會立即執行一次,并自動追蹤其依賴:
import { ref, watchEffect } from 'vue'const count = ref(0)watchEffect(() => {console.log(`count的值是: ${count.value}`)
})
9、比較watch和watchEffect
特性 | watch | watchEffect |
---|---|---|
惰性執行 | 是 | 否(立即執行) |
指定觀察源 | 需要 | 自動追蹤 |
訪問舊值 | 可以 | 不可以 |
初始化執行 | 需要配置immediate | 總是執行 |
10、最佳實踐
- ??避免過度使用??:優先使用計算屬性,只在需要副作用時使用
watch
; - ??清理副作用??:在回調中執行異步操作時,注意清理之前的操作;
- ??性能優化??:對于復雜對象,考慮使用
{ deep: true }
或特定getter
函數; - ??組件卸載時??:在
setup()
中創建的watch
會自動停止,手動創建的記得清理;
八、組合式API - 生命周期函數
在Vue 3的組合式API中,生命周期鉤子是通過特定的函數來訪問的,而不是Options API中的選項形式。
1、主要生命周期函數
onBeforeMount 和 onMounted:
import { onBeforeMount, onMounted } from 'vue'onBeforeMount(() => {console.log('組件即將掛載')
})onMounted(() => {console.log('組件已掛載')// 可以訪問DOM元素
})
onBeforeUpdate 和 onUpdated:
import { onBeforeUpdate, onUpdated } from 'vue'onBeforeUpdate(() => {console.log('組件即將更新')
})onUpdated(() => {console.log('組件已更新')// DOM已更新完成
})
onBeforeUnmount 和 onUnmounted:
import { onBeforeUnmount, onUnmounted } from 'vue'onBeforeUnmount(() => {console.log('組件即將卸載')
})onUnmounted(() => {console.log('組件已卸載')// 清理定時器、事件監聽等
})
onErrorCaptured:
import { onErrorCaptured } from 'vue'onErrorCaptured((err, instance, info) => {console.error('捕獲到錯誤:', err)// 返回false阻止錯誤繼續向上傳播return false
})
2、新增的生命周期函數
Vue 3還引入了兩個新的生命周期函數:
onRenderTracked (開發模式):
import { onRenderTracked } from 'vue'onRenderTracked((event) => {console.log('跟蹤到依賴:', event)
})
onRenderTriggered (開發模式):
import { onRenderTriggered } from 'vue'onRenderTriggered((event) => {console.log('觸發重新渲染:', event)
})
3、組合式API與Options API生命周期對應關系
組合式API | Options API |
---|---|
onBeforeMount | beforeMount |
onMounted | mounted |
onBeforeUpdate | beforeUpdate |
onUpdated | updated |
onBeforeUnmount | beforeUnmount |
onUnmounted | unmounted |
onErrorCaptured | errorCaptured |
onActivated | activated |
onDeactivated | deactivated |
4、實際應用示例
<template><div><h2>生命周期示例</h2><p>計數: {{ count }}</p><button @click="count++">增加</button></div>
</template><script setup>
import { ref, onBeforeMount, onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted
} from 'vue'const count = ref(0)onBeforeMount(() => {console.log('1. 組件即將掛載 - count:', count.value)
})onMounted(() => {console.log('2. 組件已掛載 - 可以訪問DOM')// 這里可以執行需要DOM的操作
})onBeforeUpdate(() => {console.log('3. 組件即將更新 - 舊count:', count.value)
})onUpdated(() => {console.log('4. 組件已更新 - 新count:', count.value)
})onBeforeUnmount(() => {console.log('5. 組件即將卸載')
})onUnmounted(() => {console.log('6. 組件已卸載')// 清理工作
})
</script>
5、最佳實踐
- ??邏輯組織??:將相關生命周期邏輯放在一起,保持代碼可讀性;
- ??清理工作??:在onUnmounted中清理定時器、事件監聽等資源;
- ??避免濫用??:不是所有邏輯都需要放在生命周期中,有些可以放在方法中按需調用;
- ??異步操作??:在onMounted中進行DOM操作或數據獲取;
- 性能優化??:使用onRenderTracked和onRenderTriggered調試性能問題;