vue render function Advanced Learning

On a blog I share a basic use vue render function

This blog we simply talk about how he render function was achieved

First to get an official map

In the example we have time initialization, html generated by dom render a virtual function is compiled, the view will generate a layer according to a virtual real dom dom

If the response data and then have time to change, render function will recall, was updated in time render function returns a new virtual dom, dom this new virtual and does not have to directly replace before, he will compare old and new dom, then diff algorithms, the result was the smallest changes, updates take real dom, dom have to avoid the occurrence of a large number of reflux and redraw

render function triggers the timing

Just at the top already I said, render function when it will change in response to the data is triggered, then you have to talk about responsive principle of vue

Before heard that principle is implemented vue data hijacking, he in the end is how to do data hijacking it too?

Vue source can be seen inside, inside vue instance data will add all attributes of an object into the initialization

function observe (obj) {

 // 迭代对象的所有属性
 // 并使用Object.defineProperty()转换成getter/setters
 Object.keys(obj).forEach(key => {
  let internalValue = obj[key]

// 每个属性分配一个Dep实例
const dep = new Dep()

Object.defineProperty(obj, key, {

  // getter负责注册订阅者
  get () {
    dep.depend()
    return internalValue
  },

  // setter负责通知改变
  set (newVal) {
    const changed = internalValue !== newVal
    internalValue = newVal
    
        // 触发后重新计算
        if (changed) {
          dep.notify()
        }
      }
    })
})
return obj
}

On the basis of the behavior does not change the properties of the original plus one dependent objects into it, since the object is transmitted through the notification then tells the listener watcher data has changed, then watcher to call the render function to update dom

jsx grammar render function of

Xml syntax of a class defined within jsx thing js, js code can be parsed, interpreted by js engine, on the inside I'm using a blog is written render function itself, but the feeling is very redundant, inside the very jsx Introduction, you can return all the attributes of a label, I feel no different example and html

  render() {
const { count, onChange } = this;
return (
  <div>
    <componment
      style={{ marginTop: "10px" }}
      count={count}
      type="button"
      onChange={onChange}
    />
    <componment
      style={{ marginTop: "10px" }}
      count={count}
      type="button"
      domPropsInnerHTML={`hello ${this.count}.`}
      onChange={onChange}
    />
  </div>
);
}

Top of the code can be easily rendered two components
should be noted that the use of jsx grammar when needed babel plug-in, the official plug-in connection

createElement

render函数里边用的createElement方法创建的vnode,createElement方法在vue的源码里边是对_createElement方法的封装,之前是由五个参数的,其中有一个参数是对子节点的犯规,
我们使用的createElement在经过规范化之后,默认返回的一个vnode类型的数组

vnode有四个属性

  • tag
  • data
  • context
  • children

第一个是节点的名称 首先会对tag进行一个判断,如果是字符串的话,会去看是不是html规范的一些检点,如果是的话会创建一个普通的vnode节点

如果是以恶搞注册过的组件名称,则会createComponent 创建一个组件类型的vnode

如果都不是则会创建一个位置的标签

什么是vnode

所谓虚拟DOM,是一个用于表示真实 DOM 结构和属性的 JavaScript 对象,这个对象用于对比虚拟 DOM 和当前真实 DOM 的差异化,然后进行局部渲染从而实现性能上的优化。

vnode的渲染

在render函数生成完毕虚拟dom树之后 就开始了vnode的首次渲染,vue里边调用的是_update方法

 // src/core/instance/lifecycle.js
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
const vm: Component = this
if (vm._isMounted) {
  callHook(vm, 'beforeUpdate')
}
const prevEl = vm.$el
const prevVnode = vm._vnode
const prevActiveInstance = activeInstance
activeInstance = vm
vm._vnode = vnode

if (!prevVnode) {
  // 初始化渲染
  vm.$el = vm.__patch__(
    vm.$el, vnode, hydrating, false /* removeOnly */,
    vm.$options._parentElm,
    vm.$options._refElm
  )
  // no need for the ref nodes after initial patch
  // this prevents keeping a detached DOM tree in memory (#5851)
  vm.$options._parentElm = vm.$options._refElm = null
} else {
  // 更新渲染
  vm.$el = vm.__patch__(prevVnode, vnode)
}
activeInstance = prevActiveInstance
// update __vue__ reference
if (prevEl) {
  prevEl.__vue__ = null
}
if (vm.$el) {
  vm.$el.__vue__ = vm
}
// if parent is an HOC, update its $el as well
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
  vm.$parent.$el = vm.$el
}
// updated hook is called by the scheduler to ensure that children are
// updated in a parent's updated hook.
}

可以看出不管如何最终都是调用的__patch__方法
这个__patch__方法主要有两个作用 第一个是创建真实dom 另外一个是发生变化之后把新老的虚拟dom进行对比然后更新真实dom
这个方法对应的方法是createPatchFunction() 有兴趣的可以去源码里边搜一下

结束语

以上是我对render函数的从响应到渲染还有他的作用的理解 有不对的地方欢迎批评指正

Guess you like

Origin www.cnblogs.com/netUserAdd/p/10923570.html