当前位置:首页 > VUE

proxy实现vue

2026-03-27 22:34:26VUE

使用Proxy实现Vue响应式系统

Vue 3.x 使用 Proxy 替代了 Vue 2.x 的 Object.defineProperty 来实现响应式系统。以下是核心实现方法:

创建响应式对象

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) {
      Reflect.set(target, key, value, receiver)
      trigger(target, key) // 触发更新
      return true
    }
  })
}

依赖收集与触发

proxy实现vue

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)
}

function trigger(target, key) {
  const depsMap = targetMap.get(target)
  if (!depsMap) return
  const effects = depsMap.get(key)
  effects && effects.forEach(effect => effect())
}

实现计算属性

function computed(getter) {
  let value
  let dirty = true

  const effect = effectFn(getter, {
    lazy: true,
    scheduler() {
      dirty = true
      trigger(obj, 'value')
    }
  })

  const obj = {
    get value() {
      if (dirty) {
        value = effect()
        dirty = false
      }
      track(obj, 'value')
      return value
    }
  }

  return obj
}

实现简易Vue实例

创建Vue实例

proxy实现vue

class Vue {
  constructor(options) {
    this.$options = options
    this._data = options.data()
    this.$el = document.querySelector(options.el)

    this.proxy = new Proxy(this, {
      get(target, key) {
        if (key in target._data) {
          return target._data[key]
        }
        return target[key]
      },
      set(target, key, value) {
        if (key in target._data) {
          target._data[key] = value
          target.update()
          return true
        }
        target[key] = value
        return true
      }
    })

    this.update = this.update.bind(this)
    this.effect = effectFn(() => {
      this.update()
    })

    this.update()
  }

  update() {
    this.$el.innerHTML = this.$options.render.call(this.proxy)
  }
}

使用示例

HTML部分

<div id="app"></div>

JavaScript部分

const app = new Vue({
  el: '#app',
  data() {
    return {
      count: 0
    }
  },
  render() {
    return `
      <div>
        <p>Count: ${this.count}</p>
        <button onclick="app.count++">Increment</button>
      </div>
    `
  }
})

关键点说明

Proxy相比Object.defineProperty的优势在于能直接代理整个对象,无需递归遍历属性。它能检测到属性的添加和删除,支持数组索引修改和length变化,还能拦截更多操作如in操作符。

实现时需要注意处理嵌套对象的响应式转换,避免重复代理。对于数组需要特殊处理,因为Proxy能直接拦截数组的各种变异方法。

标签: proxyvue
分享给朋友:

相关文章

vue路由实现内部切换

vue路由实现内部切换

Vue 路由实现内部切换的方法 Vue Router 是 Vue.js 官方的路由管理器,用于实现单页应用(SPA)的页面切换。以下是几种常见的内部路由切换方式: 使用 <router-lin…

vue实现用户信息表

vue实现用户信息表

Vue 实现用户信息表的方法 使用 Vue CLI 创建项目 安装 Vue CLI 并初始化项目: npm install -g @vue/cli vue create user-info-tabl…

vue实现https

vue实现https

Vue 中实现 HTTPS 的步骤 在 Vue 项目中实现 HTTPS 主要涉及开发环境配置和生产环境部署。以下是具体方法: 开发环境配置(Vue CLI 或 Vite) 使用 mkcert 生成…

vue实现异步

vue实现异步

Vue 实现异步操作的常见方法 Vue 提供了多种方式来处理异步操作,包括数据获取、事件处理等场景。 使用 async/await 在 Vue 方法中可以直接使用 async/await 语法处理异…

vue实现切换

vue实现切换

Vue 实现切换功能的方法 在 Vue 中实现切换功能可以通过多种方式实现,以下是一些常见的方法: 使用 v-if 和 v-else 指令 通过条件渲染实现切换功能,适用于简单的显示/隐藏场景。…

vue实现模块

vue实现模块

Vue 实现模块化的方法 Vue 支持多种模块化开发方式,可以根据项目需求选择适合的方案。 使用单文件组件(SFC) 单文件组件是 Vue 最常用的模块化方式,将模板、脚本和样式封装在一个 .vue…