引言
Vue 3的响应式系统是其最核心的特性之一,相比Vue 2使用的Object.defineProperty()方法,Vue 3采用了更强大的Proxy来实现响应式。本文将深入探讨Vue 3响应式系统的工作原理及其实际应用。
响应式系统基础
Proxy的优势
Vue 3选择使用Proxy而不是Object.defineProperty()主要有以下几个原因:
- 能够监听数组变化
- 能够监听对象属性的添加和删除
- 支持Map、Set、WeakMap、WeakSet
- 性能更好,不需要递归遍历对象的每个属性
基本实现原理
// 创建响应式对象
function reactive(target) {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key) // 依赖收集
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver)
trigger(target, key) // 触发更新
return result
}
})
}
核心概念解析
1. 依赖收集(track)
当组件首次渲染时,会访问响应式对象的属性,这时会触发getter,进行依赖收集:
let activeEffect // 当前正在执行的副作用函数
const targetMap = new WeakMap()
function track(target, key) {
if(!activeEffect) return
let depsMap = targetMap.get(target)
if(!depsMap) {
targetMap.set(target, (depsMap = new Map()))
}
let dep = depsMap.get(key)
if(!dep) {
depsMap.set(key, (dep = new Set()))
}
dep.add(activeEffect)
}
2. 触发更新(trigger)
当响应式对象的属性发生变化时,会触发setter,执行相关的副作用函数:
function trigger(target, key) {
const depsMap = targetMap.get(target)
if(!depsMap) return
const dep = depsMap.get(key)
if(dep) {
dep.forEach(effect => effect())
}
}
实际应用示例
1. 基础用法
import { ref, reactive } from 'vue'
// 使用ref
const count = ref(0)
console.log(count.value) // 0
count.value++
// 使用reactive
const state = reactive({
name: '张三',
age: 18
})
console.log(state.name) // 张三
state.age = 20
2. 计算属性
import { reactive, computed } from 'vue'
const state = reactive({
price: 100,
quantity: 2
})
const total = computed(() => {
return state.price * state.quantity
})
console.log(total.value) // 200
3. 监听器
import { reactive, watch } from 'vue'
const state = reactive({
count: 0
})
watch(
() => state.count,
(newValue, oldValue) => {
console.log(`count从${oldValue}变为${newValue}`)
}
)
性能优化建议
- 避免创建大型响应式对象
- 使用shallowRef或shallowReactive处理浅层响应
- 合理使用computed缓存计算结果
- 使用watchEffect替代watch处理多个依赖
常见陷阱与解决方案
1. 响应式丢失问题
const state = reactive({items: []})
// 错误方式
const { items } = state
// 正确方式
const items = computed(() => state.items)
2. 集合类型的响应式
const set = reactive(new Set())
// 直接使用Set方法
set.add(1)
set.delete(1)
总结
Vue 3的响应式系统通过Proxy实现了更强大和高效的数据响应式。理解其工作原理对于开发高性能的Vue应用至关重要。在实际应用中,需要注意响应式数据的使用方式,合理运用ref、reactive等API,同时注意避免常见陷阱。

被折叠的 条评论
为什么被折叠?



