注:纯手打,如有错误欢迎评论区交流!
转载请注明出处: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调试性能问题;