Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

04 渲染dom #6

Open
xwjie opened this issue Jan 8, 2018 · 0 comments
Open

04 渲染dom #6

xwjie opened this issue Jan 8, 2018 · 0 comments

Comments

@xwjie
Copy link
Owner

xwjie commented Jan 8, 2018

渲染函数生成之后,渲染dom就很简单,直接调用 snabbdompatch 函数即可。

调用之前,需要把data 里面的数据使用 Object.defineProperty 代理 到实例上。

  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      // log('[observer]get方法被调用,属性:' + key)
      const value = getter ? getter.call(obj) : val
      return value
    },

    set: function reactiveSetter(newVal) {
      // log('[observer]set方法被调用,属性:' + key)
      const value = getter ? getter.call(obj) : val

      /* eslint-disable no-self-compare */
     // 没有看懂后面的语句作用
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }

      if (setter) {
        setter.call(obj, newVal)
      } else {
        val = newVal
      }
    }
  }

然后就可以调用 patch 函数了。

let renderCount: number = 1;

function updateComponent(vm: Xiao) {
  let proxy = vm

  // 需要把创建对象的函数设置进去
  proxy.h = h

  // 新的虚拟节点
  let vnode = vm.$render.call(proxy)

  // 上一次渲染的虚拟dom
  let preNode = vm.$options.oldvnode;

  log(`[lifecycle] 第${renderCount}次渲染`)

  if (preNode) {
    vnode = patch(preNode, vnode)
  }
  else {
    vnode = patch(vm.$el, vnode)
  }

  renderCount++;

  // save
  vm.$options.oldvnode = vnode;
}

每次都是调用 patch 函数,第一次调用的时候,第一个参数为dom元素,第二个参数为虚拟dom,后面更新数据的时候,重新生成虚拟dom,然后把上次的虚拟dom做为第一个参数传入,再次调用 patch 函数接口。所以需要把渲染后的虚拟dom存起来。

我们看回之前生成的渲染函数render

render ƒ anonymous() {
with(this){return h("h1",{},["变量1:"+message+"。",h("br",{},[]),"变量2:"+message2+"。",])}
}

this 就是实例,在我们的例子里面,就是 Xiao 的实例。h 就是 this.h , 就是 snabbdomh 函数, messagemessage2 就是 this.messgethis.message2 , 数据就是来自于 data。是不是很清晰了?!

很简单很清晰了吧!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant