current position:Home>On Vue source code (III) single component mounting (rendering)

On Vue source code (III) single component mounting (rendering)

2021-08-26 20:09:58 Yixiu

Mind mapping

Vue Source code exploration .png

Preface

The last article mainly talked about ,Vue How the internal implementation will template convert to ats Code . And how to use ast The code generates render Functional .Vue Source code exploration ( Two ) Template compilation .

In this article, we mainly talk about how to pass render function Generate vnode,vnode Make it real dom Mount on the page , That is, as of mounted This piece of , It doesn't contain update This part of the data change , Namely Vue Initial rendering of .

 No title .png

Text

call render Generate vnode

lifecycle.js

import { patch } from "./vnode/patch"

export function mountComponent(vm) {
  // vm._render()  Get vnode 

  // vm._update(vnode)  hold vnode  Render as real nodes , Update to page 
  vm._update(vm._render())
}

export function lifeCycleMixin(Vue){
  // Give an object , Render the object real DOM
  Vue.prototype._update = function(vnode){
    // Using the pre order depth traversal , Create nodes .
    const vm = this
    patch(vm.$el, vnode)
  }
}
 Copy code 

render.js

import { isObject } from "./utils"
import { createElement, createText } from "./vnode"

export function renderMixin(Vue) {
  Vue.prototype._c = function () {
    const vm = this
    return createElement(vm, ...arguments)
  }

  Vue.prototype._v = function (text) {
    const vm = this
    return createText(vm, text)
  }

  Vue.prototype._s = function (val) {
    if (isObject(val)) return JSON.stringify(val)
    return val
  }

  // according to render  Generate vnode object 
  Vue.prototype._render = function () {
    const vm = this
    let { render } = vm.$options

    //  hold ast convert to vnode 
    let vnode = render.call(vm)
    return vnode
  }
}

// render  What a function looks like 

// function render() {
// with (this) { 
// return _c('div', { id: "app" }, _v(_s(message))) 
// }
// }
 Copy code 

vnode/index.js

export function createElement(vm, tag, data = {}, ...children) {
  return vnode(vm, tag, data, children, data.key, undefined)
}

export function createText(vm, text) {
  return vnode(vm, undefined, undefined, undefined, undefined, text)
}


function vnode(vm, tag, data, children, key, text) {
  return {
    vm,
    tag,
    data,
    children,
    key,
    text
  }
}
 Copy code 

ast And vnode The difference between ?

  • ast It describes grammar , He doesn't have the user's own logic , Only the content parsed by grammar
  • vnode Is to describe dom Structural , You can expand yourself .

according to vnode Generate reality dom

patch.js

//  use vnode Make good DOM structure   Replace (replace) Drop the original el
export function patch(el, vnode){
  // Delete old node , according to vnode Create a new node , Replace the old node .
  const elm = createElm(vnode)
  const parentNode = el.parentNode
  /*  Insert in front of the next node of the old element   Then delete the old elements  */
  parentNode.insertBefore(elm, el.nextSibling)
  parentNode.removeChild(el)
}

// Create reality DOM node 
function createElm(vnode) {
  let {tag, data, children, text, vm} = vnode
  // Element nodes 
  if(typeof tag === 'string'){
    // to vnode Add a new property to store the real DOM , Just to be able to pass vnode Find the real node and update .
    vnode.el = document.createElement(tag)
    // If there is data attribute , We need to data Set to element .
    updateProperties(vnode.el, data)
    // If you have a son, recursively create 
    children.forEach(child => {
      vnode.el.appendChild(createElm(child))
    })
  }else {
    vnode.el = document.createTextNode(text)
  }

  return vnode.el
}

function updateProperties(el, props = {}) {
  for(let key in props){
    el.setAttribute(key, props[key])
  }
}
 Copy code 

summary

This summary is mainly understood by render How to generate vnode, And turn it into reality dom Rendered to the page , This completes the rendering process of the most basic data to the page . The following section will continue to write how to notify the page when the data changes and let the page automatically trigger the update of the page . That is, the dotted ring process in the figure .

copyright notice
author[Yixiu],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210826200954060v.html

Random recommended