PrefaceThis article will explain how Vue components are parsed and rendered.
<div id="app"> <my-button></my-button> </div> <script> Vue.component("my-button", { template: "<button> Button component</button>", }); let vm = new Vue({ el:'#app' }); </script> Global component parsing principleIn order to ensure the isolation of components, each component generates a new class through the extend method to inherit the parent class. And merge the opts passed by the user through the Vue.component method into vue.options.components, and then merge Vue.options.components and vm.$options.components when vue is initialized. 1. Vue.component methodVue.options._base = Vue; //You can find vue through \_base Vue.options.components = {}; Vue.component = function (id, definition) { //Each component generates a new class to inherit the father definition = this.options._base.extend(definition); console.log("1. Create a constructor for the component, based on Vue", definition); this.options.components[id] = definition; }; 2. Vue.extend methodThe extend method generates a class that inherits from Vue and should have all the functions of the parent class. import {mergeOptions} from '../util/index' Vue.extend = function (definition) { const Vue = this; const Sub = function VueComponent(options) { this._init(options); }; Sub.prototype = Object.create(Vue.prototype); Sub.prototype.constructor = Sub; Sub.options = mergeOptions(Vue.options, definition); return Sub; }; 3. Attribute mergingMerge the definition passed in by Vue.options and Vue.component(definition) strats.components = function (parentVal, childVal) { let options = Object.create(parentVal); if (childVal) { for (let key in childVal) { options[key] = childVal[key]; } } return options; }; 4. Initialize the mergeMerge Vue.options.components and vm.$options.components Vue.prototype._init = function (options) { const vm = this; ++ vm.$options = mergeOptions(vm.constructor.options, options); //... initState(vm); if (vm.$options.el) { //Mount the data onto this template vm.$mount(vm.$options.el); } }; Okay, here we have implemented the parsing of global components. Next, let’s take a look at how the Kang Kang component is rendered. Component rendering principleWhen creating a virtual node, we need to use isReservedTag to determine whether the current tag is a component. The virtual node of a common tag is different from the virtual node of a component. If the tag is a component, a component vnode should be rendered. export function isReservedTag(str) { let reservedTag = "a,div,span,p,img,button,ul,li"; return reservedTag.includes(str); } 1. Create component virtual nodescreateComponent creates a virtual node of a component, and distinguishes whether it is a component by whether there is a hook on the data export function createElement(vm, tag, data = {}, ...children) { // If tag is a component, it should render a component's vnode if (isReservedTag(tag)) { return vnode(vm, tag, data, data.key, children, undefined); } else { const Ctor = vm.$options.components[tag] return createComponent(vm, tag, data, data.key, children, Ctor); } } // Create a virtual node for the component, in order to distinguish between components and elements data.hook function createComponent(vm, tag, data, key, children, Ctor) { // Component constructor if (isObject (Ctor)) { Ctor = vm.$options._base.extend(Ctor); // Vue.extend } data.hook = { // This initialization method needs to be called when rendering the component init(vnode){ let vm = vnode.componentInstance = new Ctor({_isComponent:true}); // new Sub will use this option and component configuration to merge vm.$mount(); // After the component is mounted, it will be in vnode.componentInstance.$el } } return vnode(vm,`vue-component-${tag}`,data,key,undefined,undefined,{Ctor,children}) } 2. Create the actual node of the componenttypeof tag === "string", it may be a virtual node of a component, then createComponent is called. export function patch(oldVnode,vnode){ // 1. Determine whether to update or render if(!oldVnode){ return createElm(vnode); }else{ // ... } } function createElm(vnode) { let { tag, data, children, text, vm } = vnode; if (typeof tag === "string") { if (createComponent(vnode)) { //Return the real node corresponding to the component return vnode.componentInstance.$el; } vnode.el = document.createElement(tag); // The virtual node will have an el attribute corresponding to the real node children.forEach((child) => { vnode.el.appendChild(createElm(child)); }); } else { vnode.el = document.createTextNode(text); } return vnode.el; } createComponent determines whether the component is a virtual node by whether there is a hook.init method on the data If yes, call data.hook.init on the component Create a component instance and assign it to vnode.componentInstance If vnode.componentInstance has a value, it means the real DOM of the corresponding component has been generated. function createComponent(vnode) { let i = vnode.data; if((i = i.hook) && (i = i.init)){ i(vnode); } if(vnode.componentInstance){ return true; } } Call the init method to create an instance of the component and mount it data.hook = { init(vnode){ let child = vnode.componentInstance = new Ctor({}); child.$mount(); // Component mounting} } summaryNew component (). $mount () => vm. $el Insert the component's $el into the parent container (parent component) It's done! The above is how Vue components are parsed and rendered? For more details about vue component parsing and rendering, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: Vue implements an Input component that gets the key display shortcut key effect
>>: Java example code to generate random characters
About let to avoid problems caused by closure Use...
This article shares the specific code of jQuery t...
Problem Description In the framework of Ele.me UI...
1. Common MySQL configuration All the following c...
Recently, students from the User Experience Team o...
Table of contents Deploy nginx on server1 Deploy ...
Grouping and linking in MYSQL are the two most co...
Preface In actual development, business requireme...
In a recent problem, there is such a phenomenon: ...
Table of contents Query Background 1. Like query ...
How to define and use: Use the slot tag definitio...
Introduction to MySQL Window Functions MySQL has ...
background: Tablespace: All INNODB data is stored...
Table of contents 1.sleep function 2. setTimeout ...
This article shares the specific code of js to re...