当前位置:首页 > VUE

js 实现vue模板

2026-02-09 13:16:51VUE

使用原生 JavaScript 实现 Vue 模板功能

通过原生 JavaScript 可以实现类似 Vue 的模板功能,包括数据绑定、指令处理和模板渲染。以下是具体实现方法:

数据绑定实现

创建一个简单的数据绑定系统,使用 Object.definePropertyProxy 实现数据响应式:

class Vue {
  constructor(options) {
    this.$options = options
    this.$data = options.data
    this.observe(this.$data)
    this.compile()
  }

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

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

模板编译

实现模板编译功能,处理插值表达式和指令:

class Vue {
  // ...其他代码

  compile() {
    const el = document.querySelector(this.$options.el)
    this.compileNode(el)
  }

  compileNode(node) {
    if (node.nodeType === 1) {
      this.compileElement(node)
    } else if (node.nodeType === 3) {
      this.compileText(node)
    }

    if (node.childNodes && node.childNodes.length) {
      Array.from(node.childNodes).forEach(childNode => {
        this.compileNode(childNode)
      })
    }
  }

  compileText(node) {
    const reg = /\{\{(.*?)\}\}/g
    const textContent = node.textContent
    if (reg.test(textContent)) {
      const key = RegExp.$1.trim()
      node.textContent = this.$data[key]
      new Watcher(this, key, value => {
        node.textContent = value
      })
    }
  }

  compileElement(node) {
    Array.from(node.attributes).forEach(attr => {
      if (attr.name.startsWith('v-')) {
        const dir = attr.name.substring(2)
        const exp = attr.value
        if (dir === 'model') {
          node.value = this.$data[exp]
          node.addEventListener('input', e => {
            this.$data[exp] = e.target.value
          })
          new Watcher(this, exp, value => {
            node.value = value
          })
        }
      }
    })
  }
}

观察者模式实现

创建 Watcher 类实现观察者模式:

js 实现vue模板

class Watcher {
  constructor(vm, key, cb) {
    this.vm = vm
    this.key = key
    this.cb = cb
    Dep.target = this
    this.value = vm.$data[key]
    Dep.target = null
  }

  update() {
    this.value = this.vm.$data[this.key]
    this.cb(this.value)
  }
}

使用方法示例

<div id="app">
  <input v-model="message" />
  <p>{{ message }}</p>
</div>

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

功能扩展

  1. 计算属性:可以通过添加 computed 选项并创建对应的 getter 函数实现
  2. 方法处理:在 Vue 实例上添加 methods 选项,并在模板中绑定事件
  3. 生命周期钩子:在特定阶段触发回调函数
  4. 组件系统:通过创建子类或工厂函数实现组件功能

这种实现方式展示了 Vue 核心功能的基本原理,实际 Vue 源码更加复杂和完善,包含虚拟 DOM、diff 算法等高级特性。

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

相关文章

js实现拖拽

js实现拖拽

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

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

js实现驼峰

js实现驼峰

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

js实现下拉菜单

js实现下拉菜单

使用HTML和CSS创建基础结构 HTML部分需要包含一个触发下拉的按钮和隐藏的下拉菜单内容: <div class="dropdown"> <button class="dr…

js图片上传实现

js图片上传实现

图片上传的基本实现 使用HTML的<input type="file">元素配合JavaScript的File API实现基础图片上传功能。HTML部分需要设置accept="image/…

js实现的游戏

js实现的游戏

JavaScript 游戏开发基础 JavaScript 是开发网页游戏的流行选择,因其无需插件即可在浏览器中运行。以下是一些关键技术和资源: HTML5 Canvas Canvas 提供了绘制图形…