当前位置:首页 > VUE

从零开始实现vue

2026-01-23 15:10:19VUE

从零实现 Vue.js 的核心功能

Vue.js 的核心功能包括数据响应式、虚拟 DOM、模板编译等。以下是一个简化版的实现思路:

数据响应式系统

通过 Object.definePropertyProxy 实现数据劫持,监听数据变化并触发更新。

class Observer {
  constructor(data) {
    this.walk(data)
  }

  walk(data) {
    if (!data || typeof data !== 'object') return
    Object.keys(data).forEach(key => {
      this.defineReactive(data, key, data[key])
    })
  }

  defineReactive(obj, key, val) {
    this.walk(val)
    const dep = new Dep()
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get() {
        Dep.target && dep.addSub(Dep.target)
        return val
      },
      set(newVal) {
        if (newVal === val) return
        val = newVal
        dep.notify()
      }
    })
  }
}

依赖收集系统

实现一个简单的发布-订阅模式来管理依赖。

从零开始实现vue

class Dep {
  constructor() {
    this.subs = []
  }

  addSub(sub) {
    this.subs.push(sub)
  }

  notify() {
    this.subs.forEach(sub => sub.update())
  }
}

Dep.target = null

编译器

实现简单的模板编译,将模板转换为渲染函数。

class Compiler {
  constructor(el, vm) {
    this.$vm = vm
    this.$el = document.querySelector(el)
    this.compile(this.$el)
  }

  compile(el) {
    const childNodes = el.childNodes
    Array.from(childNodes).forEach(node => {
      if (this.isElement(node)) {
        this.compileElement(node)
      } else if (this.isInterpolation(node)) {
        this.compileText(node)
      }
      if (node.childNodes && node.childNodes.length > 0) {
        this.compile(node)
      }
    })
  }

  isElement(node) {
    return node.nodeType === 1
  }

  isInterpolation(node) {
    return node.nodeType === 3 && /\{\{(.*)\}\}/.test(node.textContent)
  }

  compileText(node) {
    const exp = RegExp.$1.trim()
    this.update(node, exp, 'text')
  }

  compileElement(node) {
    const attrs = node.attributes
    Array.from(attrs).forEach(attr => {
      const attrName = attr.name
      const exp = attr.value
      if (this.isDirective(attrName)) {
        const dir = attrName.substring(2)
        this[dir] && this[dir](node, exp)
      }
    })
  }

  isDirective(attr) {
    return attr.startsWith('v-')
  }

  text(node, exp) {
    this.update(node, exp, 'text')
  }

  update(node, exp, dir) {
    const fn = this[dir + 'Updater']
    fn && fn(node, this.$vm[exp])
    new Watcher(this.$vm, exp, value => {
      fn && fn(node, value)
    })
  }

  textUpdater(node, value) {
    node.textContent = value
  }
}

观察者

实现 Watcher 来连接响应式系统和视图更新。

从零开始实现vue

class Watcher {
  constructor(vm, key, cb) {
    this.$vm = vm
    this.key = key
    this.cb = cb
    Dep.target = this
    this.$vm[this.key] // 触发getter,收集依赖
    Dep.target = null
  }

  update() {
    this.cb.call(this.$vm, this.$vm[this.key])
  }
}

Vue 类

整合以上功能实现基础 Vue 类。

class Vue {
  constructor(options) {
    this.$options = options
    this.$data = options.data
    new Observer(this.$data)
    this.proxy(this.$data)
    new Compiler(options.el, this)
  }

  proxy(data) {
    Object.keys(data).forEach(key => {
      Object.defineProperty(this, key, {
        get() {
          return data[key]
        },
        set(newVal) {
          data[key] = newVal
        }
      })
    })
  }
}

使用方法

创建一个简单的 Vue 实例:

<div id="app">
  {{ message }}
  <div v-text="message"></div>
</div>

<script>
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'
    }
  })
</script>

实现要点

  1. 数据响应式:通过 Object.defineProperty 或 Proxy 拦截数据访问和修改
  2. 依赖收集:在 getter 中收集依赖,在 setter 中触发更新
  3. 模板编译:将模板转换为渲染函数,解析指令和插值表达式
  4. 虚拟 DOM:可以进一步实现虚拟 DOM 和 diff 算法提高性能

这个简化实现包含了 Vue 的核心功能,实际 Vue 源码更加复杂,包含组件系统、生命周期、指令系统等更多功能。

标签: 从零开始vue
分享给朋友:

相关文章

vue 实现jqslidedown

vue 实现jqslidedown

在 Vue 中实现类似 jQuery 的 slideDown 效果,可以通过 Vue 的过渡系统或 CSS 动画结合动态样式绑定来实现。以下是几种实现方式: 使用 Vue Transition 组件…

vue实现帖子

vue实现帖子

Vue 实现帖子功能 使用 Vue 实现帖子功能需要结合前端框架和后端数据交互,以下是实现的关键步骤和代码示例。 帖子列表展示 创建帖子列表组件,使用 v-for 渲染帖子数据,通过 axios 获…

vue树形实现

vue树形实现

Vue 树形组件实现方法 使用递归组件实现树形结构 递归组件是 Vue 中实现树形结构的常见方法。通过组件调用自身的方式,可以轻松构建多层嵌套的树形结构。 <template> &l…

vue实现复选

vue实现复选

Vue 实现复选框 在 Vue 中实现复选框可以通过 v-model 指令绑定数据,同时结合 input 元素的 type="checkbox" 属性来实现。以下是几种常见的实现方式: 单个复选框…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template&g…

vue实现picker

vue实现picker

Vue 实现 Picker 组件的方法 在 Vue 中实现 Picker 组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 实现 通过 Vue 的模板和样式绑定,…