当前位置:首页 > JavaScript

js 实现vue模板

2026-03-01 15:01:57JavaScript

实现 Vue 模板的核心思路

Vue 模板的核心是通过数据绑定和虚拟 DOM 实现动态渲染。以下是一个简化版的实现思路:

数据劫持与响应式

通过 Object.definePropertyProxy 监听数据变化:

function observe(data) {
  if (!data || typeof data !== 'object') return
  Object.keys(data).forEach(key => {
    let value = data[key]
    const dep = new Dep()
    observe(value)
    Object.defineProperty(data, key, {
      get() {
        Dep.target && dep.addSub(Dep.target)
        return value
      },
      set(newVal) {
        if (newVal === value) return
        value = newVal
        observe(newVal)
        dep.notify()
      }
    })
  })
}

依赖收集系统

实现一个简单的发布-订阅模式:

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

编译模板

将模板字符串解析为 AST 并生成渲染函数:

function compile(template) {
  const ast = parse(template) // 简化的解析过程
  return generate(ast) // 生成渲染函数
}

function parse(template) {
  // 实现简单的标签和插值解析
  const stack = []
  let root
  let currentParent

  parseHTML(template, {
    start(tag, attrs) {
      const element = { tag, attrs, children: [] }
      if (!root) {
        root = element
      } else if (currentParent) {
        element.parent = currentParent
        currentParent.children.push(element)
      }
      stack.push(element)
      currentParent = element
    },
    end() {
      stack.pop()
      currentParent = stack[stack.length - 1]
    },
    chars(text) {
      if (!currentParent) return
      currentParent.children.push({
        type: 3,
        text
      })
    }
  })
  return root
}

虚拟 DOM 与渲染

实现一个简单的虚拟 DOM 和 patch 算法:

class VNode {
  constructor(tag, data, children, text) {
    this.tag = tag
    this.data = data
    this.children = children
    this.text = text
  }
}

function createElement(vnode) {
  if (vnode.text) return document.createTextNode(vnode.text)
  const el = document.createElement(vnode.tag)
  vnode.data.attrs.forEach(attr => {
    el.setAttribute(attr.name, attr.value)
  })
  vnode.children.forEach(child => {
    el.appendChild(createElement(child))
  })
  return el
}

function patch(oldVnode, vnode) {
  if (!oldVnode) {
    return createElement(vnode)
  }
  // 简化的 diff 算法
  if (oldVnode.tag !== vnode.tag) {
    const parent = oldVnode.el.parentNode
    parent.insertBefore(createElement(vnode), oldVnode.el)
    parent.removeChild(oldVnode.el)
    return
  }
  // 更新属性和子节点
  updateAttrs(oldVnode, vnode)
  updateChildren(oldVnode, vnode)
}

组件系统实现

实现基础的组件构造函数:

js 实现vue模板

class Vue {
  constructor(options) {
    this.$options = options
    this._data = options.data
    observe(this._data)
    this.$mount(options.el)
  }

  $mount(el) {
    this.$el = document.querySelector(el)
    const updateComponent = () => {
      const vnode = this.$options.render.call(this)
      patch(this._vnode, vnode)
      this._vnode = vnode
    }
    new Watcher(this, updateComponent)
  }
}

class Watcher {
  constructor(vm, fn) {
    this.vm = vm
    this.getter = fn
    this.get()
  }

  get() {
    Dep.target = this
    this.getter()
    Dep.target = null
  }

  update() {
    this.get()
  }
}

使用示例

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  },
  render() {
    return new VNode('div', { attrs: [{ name: 'id', value: 'app' }] }, [
      new VNode(null, null, null, this._data.message)
    ])
  }
})

这个实现包含了 Vue 的核心功能:数据响应式、虚拟 DOM、模板编译和组件系统。实际 Vue 的实现更加复杂,包含更多优化和功能。

标签: 模板js
分享给朋友:

相关文章

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js实现验证码

js实现验证码

使用Canvas生成图形验证码 在HTML中创建一个Canvas元素用于绘制验证码。通过JavaScript随机生成数字或字母组合,并添加干扰线、噪点等干扰元素增强安全性。 <canvas i…

elementui模板

elementui模板

ElementUI 模板使用指南 ElementUI 是一个基于 Vue.js 的组件库,提供丰富的 UI 组件,适用于快速开发中后台管理系统。以下是 ElementUI 模板的常见用法和资源推荐。…

js类实现

js类实现

使用类实现 JavaScript 功能 在 JavaScript 中,类(Class)是一种语法糖,基于原型继承机制。通过 class 关键字可以更直观地定义对象模板。 基本类定义 class…