Vue3组合式API使用心得与踩坑记录
1. 响应式系统使用技巧
1.1 ref vs reactive
// ref 适用场景
const count = ref(0)
const name = ref('张三')
const isActive = ref(true)
// reactive 适用场景
const state = reactive({
user: {
name: '张三',
age: 25
},
settings: {
theme: 'dark'
}
})
// 错误示范
const { name } = reactive({ name: '张三' }) // 解构后失去响应性
const name = ref(reactive({ value: '张三' })) // 嵌套使用,过度复杂
常见陷阱
- 解构reactive对象会失去响应性
- ref在模板中自动解包,但在JS中需要.value
- reactive不能用于原始类型
2. 生命周期钩子最佳实践
import { onMounted, onUnmounted, onUpdated } from 'vue'
export default {
setup() {
// 组合多个生命周期钩子
onMounted(() => {
console.log('组件挂载')
initializeData()
})
onUpdated(() => {
console.log('组件更新')
})
onUnmounted(() => {
console.log('组件卸载')
cleanup()
})
// 可以多次使用同一个钩子
onMounted(() => {
initializeOtherStuff()
})
}
}
3. 组合式函数(Composables)
3.1 封装可复用逻辑
// useCounter.js
import { ref, computed } from 'vue'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const double = computed(() => count.value * 2)
function increment() {
count.value++
}
function decrement() {
count.value--
}
return {
count,
double,
increment,
decrement
}
}
// 使用组合式函数
import { useCounter } from './composables/useCounter'
export default {
setup() {
const { count, double, increment } = useCounter(10)
return { count, double, increment }
}
}
最佳实践
- 组合式函数名以"use"开头
- 返回一个包含响应式状态的对象
- 保持功能单一,便于组合使用
- 考虑清理工作(如事件监听器)
4. 性能优化技巧
4.1 computed vs watch
// computed - 用于派生状态
const fullName = computed(() => {
return `${firstName.value} ${lastName.value}`
})
// watch - 用于副作用
watch(searchQuery, async (newValue) => {
const result = await fetchSearchResults(newValue)
searchResults.value = result
})
// watchEffect - 自动追踪依赖
watchEffect(() => {
console.log(`当前计数: ${count.value}`)
document.title = `计数: ${count.value}`
})
4.2 避免不必要的重渲染
// 使用shallowRef优化大型数据
const bigData = shallowRef(new BigData())
// 使用v-memo优化列表渲染
{{ expensiveComputation(item) }}