当前位置:首页 > VUE

vue怎样实现mvvm

2026-03-28 05:27:04VUE

Vue 的 MVVM 实现原理

Vue 通过数据绑定和响应式系统实现 MVVM(Model-View-ViewModel)模式,核心是数据驱动视图更新。

数据劫持(Observer)

Vue 使用 Object.definePropertyProxy 劫持数据对象的属性,在属性被访问或修改时触发依赖收集和更新。

vue怎样实现mvvm

// 简化版数据劫持
function defineReactive(obj, key) {
  let value = obj[key]
  Object.defineProperty(obj, key, {
    get() {
      console.log('收集依赖')
      return value
    },
    set(newVal) {
      if (newVal !== value) {
        console.log('触发更新')
        value = newVal
      }
    }
  })
}

依赖收集(Dep)

每个被劫持的属性都有一个 Dep 实例,用于管理所有依赖该属性的 Watcher

class Dep {
  constructor() {
    this.subs = []
  }
  addSub(sub) {
    this.subs.push(sub)
  }
  notify() {
    this.subs.forEach(sub => sub.update())
  }
}

观察者(Watcher)

Watcher 是视图和数据的桥梁,在数据变化时触发视图更新。

vue怎样实现mvvm

class Watcher {
  constructor(vm, exp, cb) {
    this.vm = vm
    this.exp = exp
    this.cb = cb
    this.value = this.get()
  }
  get() {
    Dep.target = this
    let value = this.vm[this.exp]
    Dep.target = null
    return value
  }
  update() {
    const newValue = this.vm[this.exp]
    if (newValue !== this.value) {
      this.value = newValue
      this.cb.call(this.vm, newValue)
    }
  }
}

模板编译(Compiler)

Vue 将模板编译为渲染函数,解析指令和插值表达式,创建对应的 Watcher

// 简化的文本节点编译
function compileText(node, vm) {
  const reg = /\{\{(.*)\}\}/
  if (reg.test(node.textContent)) {
    const exp = RegExp.$1.trim()
    new Watcher(vm, exp, function(value) {
      node.textContent = value
    })
    node.textContent = vm[exp]
  }
}

响应式流程

  1. 初始化时劫持数据属性
  2. 编译模板时遇到数据绑定创建 Watcher
  3. Watcher 读取数据触发 getterDep 收集依赖
  4. 数据变化时触发 setterDep 通知所有 Watcher 更新
  5. Watcher 执行回调更新视图

实现示例

class Vue {
  constructor(options) {
    this.$options = options
    this._data = options.data
    this.observe(this._data)
    this.compile()
  }
  observe(data) {
    Object.keys(data).forEach(key => {
      defineReactive(data, key)
    })
  }
  compile() {
    const el = document.querySelector(this.$options.el)
    this.compileNode(el)
  }
  compileNode(node) {
    if (node.nodeType === 1) {
      // 元素节点处理指令
    } else if (node.nodeType === 3) {
      // 文本节点处理插值
      compileText(node, this)
    }
  }
}

现代 Vue 的优化

Vue 3 改用 Proxy 实现响应式,解决了 Object.defineProperty 的局限性:

  • 无法检测新增/删除属性
  • 数组变异方法需要特殊处理
  • 性能更好
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key)
      return Reflect.get(target, key)
    },
    set(target, key, value) {
      const result = Reflect.set(target, key, value)
      trigger(target, key)
      return result
    }
  })
}

标签: vuemvvm
分享给朋友:

相关文章

vue功能实现

vue功能实现

Vue 功能实现指南 Vue.js 是一个渐进式 JavaScript 框架,广泛用于构建用户界面。以下是 Vue 功能的常见实现方法。 数据绑定 Vue 的核心功能之一是数据绑定,通过 v-mod…

vue实现颜色

vue实现颜色

Vue 实现颜色的方法 在 Vue 中实现颜色管理可以通过多种方式,以下是一些常见的方法: 使用 CSS 变量动态绑定颜色 在 Vue 组件的样式中定义 CSS 变量,并通过 Vue 的数据绑定动态…

vue实现 hover

vue实现 hover

实现 Vue 中的 hover 效果 在 Vue 中实现 hover 效果可以通过多种方式完成,以下是常见的几种方法: 使用 CSS 伪类 最简单的方式是直接使用 CSS 的 :hover 伪类,无…

vue事件实现

vue事件实现

Vue 事件实现方法 在Vue中,事件处理是通过v-on指令或@简写来实现的。以下是几种常见的事件处理方式: 使用v-on指令绑定事件 <button v-on:click="handleC…

vue实现甘特图

vue实现甘特图

使用 Vue 实现甘特图 基于开源库(如 vue-ganttastic) 安装依赖库: npm install vue-ganttastic 示例代码: <template> &l…

vue删除实现

vue删除实现

Vue 删除功能的实现方法 在 Vue 中实现删除功能通常涉及以下几个步骤: 方法一:使用数组的 splice 方法 通过索引删除数组中的元素,适用于列表渲染的场景。 methods: {…