响应式系统架构:
┌─────────────────────────────────────────────────────────┐
│ 响应式状态管理器 │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Watcher │ │ Proxy │ │ watchEffect │ │
│ │ (监听器) │◄──►│ (代理对象) │◄──►│ (副作用) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Vue组件 │ │ React组件 │ │ 普通JS代码 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘Watcher - 监听器
基本概念
Watcher是观察者模式的具体实现,用于监听数据变化并执行相应操作。
核心作用
监听特定数据的变化
数据变化时自动执行回调
实现数据和视图的自动同步
Proxy - 代理对象
基本概念
Proxy是ES6提供的元编程特性,可以拦截并自定义对象的操作。
核心特性
拦截对象的所有操作(读取、设置、删除等)
深度监听对象变化
不需要遍历对象属性
watchEffect - 副作用监听
基本概念
watchEffect是Vue 3的Composition API,用于自动追踪依赖的副作用函数。
核心特点
自动收集依赖,无需指定监听属性
立即执行一次
依赖变化时自动重新执行
Vue.js 中的监听
1. watch 选项
export default {
data() {
return {
count: 0,
user: {
name: '张三',
age: 25
}
}
},
watch: {
// 简单监听
count(newVal, oldVal) {
console.log('count 变化:', oldVal, '→', newVal);
},
// 对象深度监听
user: {
handler(newVal, oldVal) {
console.log('user 变化:', newVal);
},
deep: true, // 深度监听
immediate: true // 立即执行一次
},
// 监听对象的特定属性
'user.name'(newVal, oldVal) {
console.log('用户名变化:', oldVal, '→', newVal);
}
}
}2. watchEffect
import { ref, watchEffect } from 'vue'
const count = ref(0);
const name = ref('张三');
// 自动追踪依赖
watchEffect(() => {
console.log(`监听: count=${count.value}, name=${name.value}`);
});
// 当 count 或 name 变化时,自动重新执行
count.value = 10; // 触发
name.value = '李四'; // 触发3. watch API (Vue 3 Composition API)
import { ref, watch, reactive } from 'vue'
const count = ref(0);
const state = reactive({ name: '张三', age: 25 });
// 监听单个 ref
watch(count, (newVal, oldVal) => {
console.log('count 变化:', oldVal, '→', newVal);
});
// 监听 getter 函数
watch(() => state.name, (newVal, oldVal) => {
console.log('name 变化:', oldVal, '→', newVal);
});
// 监听多个源
watch([count, () => state.name], ([newCount, newName], [oldCount, oldName]) => {
console.log('批量监听:', { newCount, newName, oldCount, oldName });
});4.响应式状态管理器
class ReactiveStore {
constructor(initialState = {}) {
this.state = new Proxy(initialState, {
set: (target, property, value) => {
const oldValue = target[property];
target[property] = value;
this.notify(property, value, oldValue);
return true;
}
});
this.watchers = {};
}
watch(property, callback) {
if (!this.watchers[property]) {
this.watchers[property] = [];
}
this.watchers[property].push(callback);
}
notify(property, newValue, oldValue) {
if (this.watchers[property]) {
this.watchers[property].forEach(callback => callback(newValue, oldValue));
}
}
}
// 使用
const store = new ReactiveStore({ count: 0 });
store.watch('count', (newVal, oldVal) => {
console.log('store.count 变化:', oldVal, '→', newVal);
});
store.state.count = 5;