preface

This article is only to record their own learning process, there are other understanding students can leave a message. Note that I’ve been working on a 28 strategy where 20 percent of the code implements 80 percent of the functionality, so in this series we’re just going to focus on the core logic and implementation of the functionality


The body of the

The last article introduced the reactive principle of Vue. During Vue instantiation, after initializing the data, it enters the rendering process

The entrance

if (vm.$options.el) {
  vm.$mount(vm.$options.el)
}
Copy the code

What does $mount(el) roughly do?

$option. render = $option. render = $option. render = $option. render = $option. render = $option. render Prototype.$mount = function (el) {const vm = this; const options = vm.$options; el = document.querySelector(el); // If there is no render attribute if (! Options. render) {// Let template = options.template; if (! Template &&el) {// if there is no render and template but there is an el attribute, assign the template to the outerHTML structure of the el. Template = el.outerhtml; } // compileToFunctions(template) {const render = function (template); options.render = render; }} // Mount the current component instance to the real EL node, where el is the real DOM of options.el. };Copy the code

CompileToFunctions (template) gets render

// Parser: template is split with re to get an AST object // optimization: tag static node // generate: Generate render Function // concatenate string // with syntax // new Function (string)Copy the code

Component mounts the core method mountComponent

Export function mountComponent(vm, el) {// The real el option is assigned to the instance's $el attribute.$el = el; // _update and._render methods are both mounted on Vue prototype methods like _init vm._update(vm._render()); }Copy the code

Analyze the _render() function; Generate vnode

Vue.prototype._render = function () { const vm = this; const { render } = vm.$options; Const vnode = render. Call (vm); return vnode; }; // The render function generates a vnode based on the latest data. Function (){return _c(tag, {attribute, instruction, etc.}, child node)} <div id="contain"> <span>{{name}}</span> </div> 'contain'}}, [_c('span', {}, [name])])} // Class Vnode {constructor(tag, data, key, children, text) {this.tag = tag; this.data = data; this.key = key; this.children = children; this.text = text; . Vnode function createElement(tag, data = {},... children) { let key = data.key; return new Vnode(tag, data, key, children); } vnode function createTextNode(text) {return new vnode (undefined, undefined, undefined, text); } Vue.prototype._c = createElement; Vue.prototype._v = createTextNode;Copy the code

Core method _update (); This article only covers the initial rendering process

Prototype._update = function (vnode) {const vm = this; // Patch is render vNode as real DOM core patch(vm. }; Function patch(oldVnode, vnode) {// $el = options.el const isRealElement = oldVnode. Const oldElm = oldVnode; if (isRealElement) {const oldElm = oldVnode; const parentElm = oldElm.parentNode; // Convert virtual DOM to real DOM let el = createElm(vnode); parentElm.insertBefore(el, oldElm.nextSibling); // Remove the old el node parentelm. removeChild(oldVnode); this.$el = el; return el; } // Create a dom tree by calling the native method. // Create dom // update property updateProperties(vNode) // Create recursively if there are children, add them to the parent element // Component tags such as tag to perform beforeMount, enter the initialization process of the child of the current component, BeforeMount // the component will mount the dom after initialization, The parent beforeCreate creates the parent beforeCreate. The parent beforeCreate creates the parent beforeCreate. CreateElm (vnode) {let {tag, data, key, children, text} = vnode; if (typeof tag === "string") { vnode.el = document.createElement(tag); // Parse the virtual DOM property updateProperties(vNode); Children. ForEach ((child) => {return vnode.el.appendChild(createElm(child)); }); } else {// text node vnode.el = document.createTextNode(text); } return vnode.el; } / / parsing vnode data attributes mapped to real function on dom updateProperties (vnode) {let newProps = vnode. Data | | {}; let el = vnode.el; If (key === "style") {for (let styleName in newProps) {// If (key === "style") {for (let styleName in newProps) { el.style[styleName] = newProps.style[styleName]; } } else if (key === "class") { el.className = newProps.class; El.setattribute (key, newProps[key]); }}}Copy the code

Mind mapping

If you found this article helpful, please like, bookmark or comment. Thank you very much!