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
Context definition and purpose Context provides a...
MySQL server has gone away issue in PHP 1. Backgr...
Recently I changed Apache to nginx. When I moved ...
Table of contents Preface How to implement Vuex f...
The DATE_ADD() function adds a specified time int...
This article shares with you the Ubuntu server ve...
MySQL is a relational database management system ...
When we open the source code of a regular website...
mysql id starts from 1 and increases automaticall...
The automatic scrolling effect of the page can be...
Preface: The storage engine is the core of the da...
After the green version of mysql5.6 is decompress...
MySQL trigger simple example grammar CREATE TRIGG...
Table of contents 1. Modify the app.vue page 2. C...
Install virtualization software Before installing...