vue2简易实现
vue2 简易实现方法
Vue2 的简易实现可以通过手动构建核心功能来完成。以下是关键步骤:
数据响应式
使用 Object.defineProperty 实现数据劫持:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
return val
},
set(newVal) {
if (newVal === val) return
val = newVal
// 触发更新
}
})
}
依赖收集
创建 Dep 类管理依赖:
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.forEach(sub => sub.update())
}
}
观察者模式
实现 Watcher 类:
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])
}
}
模板编译
简单模板解析示例:
function compile(el, vm) {
vm.$el = document.querySelector(el)
const fragment = document.createDocumentFragment()
let child
while (child = vm.$el.firstChild) {
fragment.appendChild(child)
}
function replace(frag) {
Array.from(frag.childNodes).forEach(node => {
const txt = node.textContent
const reg = /\{\{(.*?)\}\}/g
if (node.nodeType === 3 && reg.test(txt)) {
const key = RegExp.$1.trim()
new Watcher(vm, key, function(val) {
node.textContent = txt.replace(reg, val)
})
node.textContent = txt.replace(reg, vm[key])
}
})
}
replace(fragment)
vm.$el.appendChild(fragment)
}
完整示例
组合以上功能:
class Vue {
constructor(options) {
this.$options = options
this.$data = options.data
this.observe(this.$data)
compile(options.el, this)
}
observe(data) {
Object.keys(data).forEach(key => {
defineReactive(this, key, data[key])
})
}
}
注意事项
- 此实现省略了数组处理、虚拟DOM等复杂功能
- 实际项目中应使用官方Vue2库
- 仅用于理解Vue2核心原理
以上代码展示了Vue2最基础的响应式原理实现,包含数据劫持、依赖收集和模板编译等核心功能。







