Vue advanced usage tutorial dynamic components

Vue advanced usage tutorial dynamic components

I believe that dynamic components will be used most of the time in the development process. When we need to switch states between different components, dynamic components can meet our needs very well. The core of this is the use of the component tag and the is attribute.

Basic description

// vue
<div id="app">
  <button @click="changeTabs('child1')">child1</button>
  <button @click="changeTabs('child2')">child2</button>
  <button @click="changeTabs('child3')">child3</button>
  <component :is="chooseTabs">
  </component>
</div>
// js
var child1 = {
  template: '<div>content1</div>',
}
var child2 = {
  template: '<div>content2</div>'
}
var child3 = {
  template: '<div>content3</div>'
}
var vm = new Vue({
  el: '#app',
  components:
    child1,
    child2,
    child3
  },
  methods: {
    changeTabs(tab) {
      this.chooseTabs = tab;
    }
  }
})

AST parsing

The interpretation of <component> is consistent with the previous articles. It will start from the AST parsing stage. The process will not focus on every detail, but will specifically explain the differences from previous processing methods. The differences in dynamic component parsing are focused on processComponent. Due to the existence of the is attribute on the tag, it will mark the component attribute on the final ast tree.

// Analysis of dynamic components function processComponent (el) {
  var binding;
  // Get the value corresponding to the is attribute if ((binding = getBindingAttr(el, 'is'))) {
    // The ast tree has an additional component attribute el.component = binding;
  }
  if (getAndRemoveAttr(el, 'inline-template') != null) {
    el.inlineTemplate = true;
  }
}

Render Function

With the ast tree, the next step is to generate an executable render function based on the ast tree. Due to the component attribute, the generation process of the render function will go through the genComponent branch.

//render function generation function var code = generate(ast, options);

// implementation of generate function function generate (ast,options) {
  var state = new CodegenState(options);
  var code = ast ? genElement(ast, state) : '_c("div")';
  return {
    render: ("with(this){return " + code + "}"),
    staticRenderFns: state.staticRenderFns
  }
}

function genElement(el, state) {
  ···
  var code;
  // Dynamic component branch if (el.component) {
    code = genComponent(el.component, el, state);
  }
}

The processing logic for dynamic components is actually very simple. When there is no inline template flag (which will be discussed later), the subsequent child nodes are obtained for splicing. The only difference from ordinary components is that the first parameter of _c is no longer a specified string, but a variable representing the component.

// Processing function for dynamic components genComponent (
    componentName,
    el,
    state
  ) {
    // When the inlineTemplate attribute is set, children is null
    var children = el.inlineTemplate ? null : genChildren(el, state, true);
    
    return ("_c(" + componentName + "," + (genData$2(el, state)) + 
    (children ? ("," + children) : '') + ")")
  }

Comparison between normal components and dynamic components

Render function of ordinary components

"with(this){return _c('div',{attrs:{"id":"app"}},[_c('child1',[_v(_s(test))])],1)}"

Dynamic component render function

"with(this){return _c('div',{attrs:{"id":"app"}},[_c(chooseTabs,{tag:"component"})],1)}"

To summarize briefly, the difference between dynamic components and ordinary components is:

  1. The component attribute is added in the ast stage, which is a sign of dynamic components
  2. During the render function generation phase, due to the existence of the component attribute, the genComponent branch will be executed. genComponent will perform special processing on the execution function of dynamic components. Unlike ordinary components, the first parameter of _c is no longer an unchanging string, but a specified component name variable.
  3. The process from render to vnode is the same as that of ordinary components, except that the string is replaced with a variable and has a data attribute of { tag: 'component' }. In this example, chooseTabs takes child1.

Dynamic components in factory function form

You can also use dynamic components in the form of factory functions as follows:

const AsyncComponent = () => ({

  // Component to load (should be a `Promise` object)

  component: import('./MyComponent.vue'),

  //Component loading used when asynchronous component loading: LoadingComponent,

  // Component used when loading fails error: ErrorComponent,

  // Display the delay time of the component during loading. The default value is 200 (milliseconds)

  delay: 200,

  // If a timeout is provided and the component load times out,

  // Use the component used when loading fails. Default value is: `Infinity`

  timeout: 3000

});



components:

  AsyncComponent,

},

Summarize

This is the end of this article about advanced usage of Vue dynamic components. For more relevant Vue dynamic component content, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue dynamic component instance analysis
  • Detailed explanation of Vue dynamic components and asynchronous components examples
  • Two ways to implement Vue dynamic subcomponents
  • Two ways to dynamically create components in Vue
  • Detailed explanation of Vue custom dynamic component example
  • Basic tutorial on using Vue dynamic components in front-end architecture

<<:  Solve the problem of managing containers with Docker Compose

>>:  HTML input box optimization to improve user experience and ease of use

Recommend

Docker image import and export code examples

Import and export of Docker images This article i...

How to count the number of specific characters in a file in Linux

Counting the number of a string in a file is actu...

A record of pitfalls in JS regular matching

I recently discovered a pitfall in regular expres...

A simple example of using Vue3 routing VueRouter4

routing vue-router4 keeps most of the API unchang...

HTML cellpadding and cellspacing attributes explained in pictures

Cell -- the content of the table Cell margin (tabl...

js to create a carousel effect

I think the carousel is a relatively important po...

Detailed explanation and examples of database account password encryption

Detailed explanation and examples of database acc...

Introduction to fork in multithreading under Linux

Table of contents Question: Case (1) fork before ...

Steps for installing MySQL 8.0.16 on Windows and solutions to errors

1. Introduction: I think the changes after mysql8...

How to deploy FastDFS in Docker

Install fastdfs on Docker Mount directory -v /e/f...

ElementUI implements sample code for drop-down options and multiple-select boxes

Table of contents Drop-down multiple-select box U...

Detailed explanation of the basic usage of VUE watch listener

Table of contents 1. The following code is a simp...

HTML input box optimization to improve user experience and ease of use

In order to improve user experience and ease of us...

A brief discussion of 3 new features worth noting in TypeScript 3.7

Table of contents Preface Optional Chaining Nulli...

CSS3 overflow property explained

1. Overflow Overflow is overflow (container). Whe...