当前位置:首页 > 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 中可以通过动态组件配合递归组件实现多级弹窗。定义一个基础弹窗组件,通过递归调用自身实现层级嵌套。 基础弹窗组件模板示例: &…

vue 实现拖动

vue 实现拖动

Vue 实现拖动的几种方法 在Vue中实现拖动功能可以通过多种方式,包括原生HTML5的拖放API、第三方库如vuedraggable等。以下是几种常见的实现方法: 使用HTML5拖放API HTM…

vue实现tree

vue实现tree

Vue 实现 Tree 组件 使用 Vue 实现 Tree 组件可以通过递归组件的方式来实现层级结构展示。以下是一个完整的实现方法: 基础递归组件实现 创建 Tree 组件文件 Tree.vue,使…

vue mvvm 实现

vue mvvm 实现

Vue MVVM 实现原理 Vue.js 的 MVVM(Model-View-ViewModel)架构通过数据绑定和响应式系统实现视图与数据的自动同步。以下是其核心实现机制: 数据劫持与响应式系统…

js 实现vue

js 实现vue

实现 Vue 的核心功能 在 JavaScript 中实现 Vue 的核心功能需要模拟数据绑定、虚拟 DOM 和响应式系统。以下是一个简化版的实现思路: 响应式系统 通过 Object.define…

vue实现tip

vue实现tip

Vue实现Tooltip的方法 使用Vue实现Tooltip可以通过多种方式完成,以下是几种常见的方法: 使用原生HTML的title属性 在Vue模板中直接使用HTML的title属性是最简单的实…