Skip to content

Commit

Permalink
feat: implement mvvm
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangdaiyan committed Apr 18, 2019
1 parent 67dab1d commit 664aef6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
26 changes: 23 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ class Vue {

return this
}
update () {
const parent = this.$el.parent

This comment has been minimized.

Copy link
@spenggithub

spenggithub May 6, 2019

这边应该是parentNode吧

This comment has been minimized.

Copy link
@zzz945

zzz945 May 6, 2019

Owner

嗯,由于testcase没覆盖到,没有暴露问题。后面会修复,可以参考下最新代码


if (parent) {
parent.removeChild(this.$el)
}

const vnode = this.$options.render.call(this.proxy, this.createElement)
this.$el = this.patch(null, vnode)

This comment has been minimized.

Copy link
@zzz945

zzz945 Apr 20, 2019

Owner

前面remove掉旧的,这里append新的,会改变$el在parent中的位置。应该用replaceChild

if (parent) {
parent.appendChild(this.$el)
}
}
patch (oldVnode, newVnode) {
return this.createElm(newVnode)
}
createElement(tag, data, children) {
return new VNode(tag, data, children)
}
Expand All @@ -43,8 +60,8 @@ class Vue {
el.addEventListener(key, events[key])
}

if (typeof vnode.children === 'string') {
el.textContent = vnode.children
if (!Array.isArray(vnode.children)) {
el.textContent = vnode.children + ''
} else {
vnode.children.forEach(child => {
if (typeof child === 'string') {
Expand Down Expand Up @@ -76,7 +93,10 @@ class Vue {
get: (_, key) => {
const methods = this.$options.methods || {}

if (key in data) return data[key] // 优先取data
if (key in data) { // 优先取data
this.$watch(key, this.update.bind(this)) // 依赖收集
return data[key]
}
if (key in methods) return methods[key].bind(this.proxy)
else return this[key]
}
Expand Down
20 changes: 20 additions & 0 deletions test/mvvm.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Vue from "../src/index.js";

describe('Mvvm', function() {
it('Basic', function() {
const vm = new Vue({
data () {
return {
a: 0,
}
},
render (h) {
return h('div', null, this.a)
}
}).$mount()

This comment has been minimized.

Copy link
@zzz945

zzz945 Apr 30, 2019

Owner

<场景分析>
首次渲染时,会触发对a的读,从而触发对a的依赖收集。
后面,当a改变时触发update, update首先调用render生成新vnode,再经过patch生成dom,赋值给$el。

vm.a++
expect(vm.$el.textContent).toBe('1')
vm.a = 999
expect(vm.$el.textContent).toBe('999')
});
});

0 comments on commit 664aef6

Please sign in to comment.