当前位置:首页 > 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)
}

组件系统实现

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

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 实现vue模板

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

相关文章

js实现验证码

js实现验证码

实现验证码的JavaScript方法 生成随机验证码 使用Math.random()生成随机字符串,结合数字和字母: function generateCaptcha() { const cha…

css网页制作模板

css网页制作模板

CSS 网页制作模板 CSS 网页制作模板通常包含基础的 HTML 结构和 CSS 样式,帮助快速搭建响应式、现代化的网页布局。以下是一个常见的模板示例,包含关键部分和优化建议。 基础 HTML 结…

js实现倒计时

js实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callbac…

CSS模板网站制作

CSS模板网站制作

CSS模板网站制作指南 CSS模板网站制作涉及多个关键步骤,从设计到实现,以下为详细方法: 选择模板或框架 使用现成的CSS框架如Bootstrap、Tailwind CSS或Foundation可…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…

js实现图

js实现图

JavaScript 实现图的常用方法 在 JavaScript 中,图(Graph)可以通过多种方式实现,常见的包括邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix…