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!