preface

  • Article ideas article and implement article 】 【 】, in this paper, in order to achieve the first edition, at the end of the article is the second edition link, synchronous read advice to see two window, or please read – “the Vue | | article implementation ast

Implement template writing compatibility

Check whether there is el attribute during initialization, if there is, execute $mount method (to achieve user self-control mount timing)
init.js
 Vue.prototype._init = function (options) {
        const vm = this;
        vm.$options = options;

        // Initialize the data
        initState(vm)

        if(vm.$options.el){ vm.$mount(vm.$options.el); }}Copy the code
$mount = “render”
If there is no template, get the HTML string from EL and assign to template. Render function will be generated from template through compilerToFunction
Vue.prototype.$mount = function (el){
    const vm = this;
    const options = vm.$options;
    el = document.querySelector(el);
    if(! options.render){// If there is no render attribute, check whether there is a template
        let template = options.template;
        // If there is no template and el is present, the el content is assigned to template
        if(! template && el){ template = el.outerHTML; }constrender = compilerToFunction(template); options.render = render; }}Copy the code

Implement the Render method

Define the VDOM structure{tag,data,key,children,text }And a function to create a VDOM from that information
vdom/index.js
function createElement(tag,data={},... children) {
    let key = data.key;
    if(key){
        delete data.key;
    }
    return vnode(tag,data,key,children); 
}
function createTextVnode(text) {
    return vnode(undefined.undefined.undefined.undefined,text)
}
// Generating virtual DOM differs from AST in that you can customize the data format
function vnode(tag,data,key,children,text) {
    return {
        tag,data,key,children,text
    }
}
Copy the code
Pass _c to render and get the render function return value, which is a VDOM
vdom/index.js
Vue.prototype._c = function () { // Create the element
        returncreateElement(... arguments); }Copy the code
Render pages with VDOM using deep traversal + DOM processing
  • Generate the corresponding HTML structure through VNode, and pay attention to handling attributes
  • Find the mount point via EL and replace it
 Vue.prototype._update = function (vnode) {
        console.log("= = = = = = = =",vnode);
        const vm = this;
        patch(vm.$el,vnode)
    }
Copy the code
vdom/patch.js

Render page entry functions according to VNode

function patch(oldVnode,vnode){
    // oldVnode is the real DOM corresponding to EL when first rendered
    const isRealElement = oldVnode.nodeType;
    if(isRealElement){
        const oldElm = oldVnode;
        const parentElm = oldElm.parentNode;
        // Use vNode to generate the corresponding HTML structure
        let el = createElm(vnode);
        // Replace the mount point
        parentElm.insertBefore(el,oldElm.nextSibling);
        parentElm.removeChild(oldVnode)
   		returnel; }}Copy the code

Create a real DOM based on a VNode

function createElm(vnode){
    let {tag,children,key,data,text} = vnode;
    if(typeof tag === 'string'){
        vnode.el = document.createElement(tag);
        // Handle attributes
        updateProperties(vnode);
        children.forEach(child= > { 
            return vnode.el.appendChild(createElm(child));
        });
    }else{
        vnode.el = document.createTextNode(text);
    }
    return vnode.el
}
Copy the code

Processing properties

function updateProperties(vnode){
    let newProps = vnode.data || {}; // Get attributes in the current old node
    let el = vnode.el; // The current real node
    for(let key in newProps){
        if(key === 'style') {for(let styleName in newProps.style){
                el.style[styleName] = newProps.style[styleName]
            }
        }else if(key === 'class'){
            el.className= newProps.class
        }else{ // Add attribute values to this elementel.setAttribute(key,newProps[key]); }}}Copy the code

A link to the

  • Vue – ast article second edition | | realizing ast/vnode and page rendering
  • Vue | | article implementation ast