Skip to content

createReactive

将普通对象转换为响应式对象,支持属性变化监听。

函数签名

typescript
function createReactive<T extends Record<string, any>>(
  target: T,
  deps: CreateReactiveDeps
): Reactive<T>

interface CreateReactiveDeps extends ReactiveDeps {
  /** 创建代理对象 */
  createProxy: <T extends Record<string, any>>(target: T, deps: ReactiveDeps) => T
  /** 获取变化路径 */
  getChangePath: (target: any, property: string | symbol) => string[]
}

前置依赖

依赖参数

参数名类型说明
deps.subscribersSet<(...args: any[]) => void>订阅者集合,用于存储所有监听器
deps.notify() => void通知函数,当状态变化时调用所有订阅者
deps.subscribe(listener: () => void) => () => void订阅函数,添加监听器并返回取消订阅函数
deps.dispose() => void清理函数,清除所有订阅者
deps.createProxy<T>(target: T, deps: ReactiveDeps) => T代理创建函数,返回包装了响应式逻辑的代理对象
deps.getChangePath(target: any, property: string | symbol) => string[]路径获取函数,返回属性变化的路径数组

环境要求

  • Proxy: 现代浏览器和 Node.js 环境支持
bash
# Node.js 环境已内置支持
# 浏览器环境需要现代浏览器(IE11+ 或其他现代浏览器)

参数

参数名类型必填说明
targetT要转换为响应式的目标对象
depsCreateReactiveDeps环境依赖,包含所有需要的函数

返回值

类型说明
Reactive<T>响应式对象,扩展了原始对象类型并添加响应式方法

工作原理

  1. 代理包装:使用 Proxy 创建目标对象的代理,拦截属性访问和修改
  2. 订阅管理:维护订阅者集合,支持添加和移除监听器
  3. 变化检测:监听对象属性的 setdeleteProperty 操作
  4. 通知机制:当属性发生变化时,自动调用所有订阅者函数
  5. 嵌套支持:支持嵌套对象的响应式变化追踪
  6. 动态属性:支持动态添加和删除对象属性

响应式对象特性

  • 保持原始对象的所有属性和方法
  • 添加 subscribe()notify()dispose() 等响应式方法
  • 透明代理,不改变原始对象的使用方式
  • 支持嵌套对象的深度响应式

异常

错误类型触发条件错误信息
TypeError目标对象不支持代理Cannot create proxy with a non-object as target

完整示例

typescript
import { createReactive } from 'zcw-shared/reactive/createReactive'

// 准备目标对象
const state = {
  count: 0,
  name: '响应式对象',
  nested: { value: 100 }
}

// 创建响应式对象
const reactiveState = createReactive(state, {
  subscribers: new Set(),
  notify: () => {
    console.log('状态发生变化!')
  },
  subscribe: (listener) => {
    reactiveState.subscribers.add(listener)
    return () => reactiveState.subscribers.delete(listener)
  },
  dispose: () => reactiveState.subscribers.clear(),
  createProxy: (target, deps) => new Proxy(target, {
    get(target, property) {
      // 响应式方法直接返回
      if (property === 'subscribe' || property === 'notify' ||
          property === 'dispose' || property === 'subscribers') {
        return deps[property as keyof typeof deps]
      }
      return target[property as keyof typeof target]
    },
    set(target, property, value) {
      const oldValue = target[property as keyof typeof target]
      ;(target as any)[property] = value
      deps.notify()
      return true
    },
    deleteProperty(target, property) {
      if (property in target) {
        delete target[property as keyof typeof target]
        deps.notify()
        return true
      }
      return false
    }
  }),
  getChangePath: (target, property) => [String(property)]
})

// 使用响应式对象
console.log(reactiveState.count) // 0

// 添加监听器
const unsubscribe = reactiveState.subscribe(() => {
  console.log('当前状态:', reactiveState)
})

// 修改属性会触发通知
reactiveState.count = 1        // 输出: 状态发生变化!
reactiveState.name = '新名称'   // 输出: 状态发生变化!
reactiveState.nested.value += 10 // 输出: 状态发生变化!

console.log(reactiveState.count) // 1

// 取消订阅
unsubscribe()

// 清理所有订阅
reactiveState.dispose()

实际应用场景

typescript
// 简单状态管理
const appState = createReactive({
  user: { name: '', age: 0 },
  settings: { theme: 'light', language: 'zh' }
}, reactiveDeps)

// 组件状态监听
const unsubscribe = appState.subscribe(() => {
  updateUI(appState)
})

// 数据驱动更新
function updateUI(state) {
  userNameElement.textContent = state.user.name
  themeClass = state.settings.theme
}

响应式系统是现代前端框架的核心特性,通过 createReactive 可以轻松实现数据驱动的界面更新。