Come straight to the point

What if you want to refresh the child table-template component in Vue, as shown below?

For example, if I change the value of the list, the child component needs to refresh it.

<template>
  <div class="wrapper">
    <table-template
      ref="table"
      :columnData="fieldDetail.column"
      :listData="fieldDetail.list"
    />
  </div>
</template>
Copy the code

General method

Method 1:

Define a reload method in the child component table-template to refresh the data

this.$refs['table'].reload()
Copy the code

Instead, I want the entire subcomponent to reload and go through the life cycle again. Well, try the V-if instruction.

Method 2:

The V-if directive, during which the element and its data binding/component are destroyed and rebuilt

<template>
  <div class="wrapper">
    <table-template
      v-if="showFlag"
      ref="table"
      :columnData="fieldDetail.column"
      :listData="fieldDetail.list"
    />
  </div>
</template>
Copy the code
this.showFlag = false;
this.$nextTick(()=>{
  this.showFlag = true;
})
Copy the code

Small coup

Refreshes components by binding key values

Triggers the component’s lifecycle hook completely

<template>
  <div class="wrapper">
    <table-template
      :key="fieldDetail.timer"
      :columnData="fieldDetail.column"
      :listData="fieldDetail.list"
    />
  </div>
</template>
Copy the code
this.fieldDetail.list = res.data
this.fieldDetail.timer = new Date().getTime();
Copy the code

Tips:

The special attribute of key is mainly used in the virtual DOM algorithm of Vue to identify VNodes when comparing old and new nodes.

If keys are not used, Vue uses an algorithm that minimizes dynamic elements and tries to modify/reuse the same type of elements in place whenever possible.

With a key, it rearranges the elements based on the change in the key and removes elements where the key does not exist.

Child elements that have the same parent must have a unique key. Duplicate keys cause render errors.

The most common use case is the combination of V-for

<ul>
  <li v-for="item in items" :key="item.id">.</li>
</ul>
Copy the code

It can also be used to force elements/components to be replaced rather than reused. It can be useful when you encounter situations like:

1. Trigger the component’s lifecycle hook completely

2. Trigger the transition

Such as:

<transition>
  <span :key="text">{{ text }}</span>
</transition>
Copy the code

When a text changes, it is always replaced rather than modified, thus triggering a transition.

The principle behind it

The principle behind, need to start from Vue’s virtual DOM diff algorithm.

The purpose of the diff algorithm for the virtual DOM is to render every change to the browser page as quickly as possible.

For example, a house is being renovated.

There are two options:

1. Demolish and rebuild;

2. Fine contrast and change where you need to.

Diff stands for fine contrast.

Virtual DOM

React and Vue both use the virtual DOM, so when data changes, local changes can be refreshed rather than rerendered as a whole.

Brief explanation, two sentences:

1. Create a virtual DOM tree structure through JavaScript and present it to the page.

2. When the data is changed, the DOM tree structure will be changed, and a new virtual DOM tree will be generated to compare with the previous DOM. The changed part will be applied to the real DOM tree and rendered to the page.

So how does the virtual DOM relate to key values?

The relationship between virtual DOM and key values

First, let’s take a look at the virtual DOM in Vue looks like, source code is as follows:

export default class VNode {
  constructor (tag? : string, data? : VNodeData, children? :?Array<VNode>, text? : string, elm? : Node, context? : Component, componentOptions? : VNodeComponentOptions, asyncFactory? :Function
  ) {
    this.tag = tag                                /* Label name of the current node */
    this.data = data        /* The object corresponding to the current node, which contains specific data information, is a VNodeData type, you can refer to the VNodeData type data information */
    this.children = children  /* The child of the current node is an array */
    this.text = text     /* The text of the current node */
    this.elm = elm       /* The actual DOM node corresponding to the current virtual node */
    this.ns = undefined            /* Namespace of the current node */
    this.context = context          /* Vue instance corresponding to the current component node */
    this.fnContext = undefined       /* The Vue instance of the functional component */
    this.fnOptions = undefined
    this.fnScopeId = undefined
    this.key = data && data.key           /* The key attribute of the node, which is used as the node's identifier, is used to optimize */
    this.componentOptions = componentOptions   /* The component's option */
    this.componentInstance = undefined       /* The instance of the component corresponding to the current node */
    this.parent = undefined           /* The parent of the current node */
    this.raw = false         InnerHTML is true, and textContent is false*/
    this.isStatic = false         /* Static node flag */
    this.isRootInsert = true      /* Whether to insert as the heel node */
    this.isComment = false             /* Is a comment node */
    this.isCloned = false           /* Whether the node is a clone */
    this.isOnce = false                /* Whether there is a v-once instruction */
    this.asyncFactory = asyncFactory
    this.asyncMeta = undefined
    this.isAsyncPlaceholder = false
  }

  get child (): Component | void {
    return this.componentInstance
  }
}
Copy the code
this.key = data && data.key           
/* The key attribute of the node, which is used as the node's identifier, is used to optimize */
Copy the code

Key helps determine whether old and new VDOM nodes are logically the same object.

Using a key to give each node a unique identity, the DIff algorithm can correctly identify the node.

The key’s main purpose is to update the virtual DOM efficiently.

Then why use the virtual DOM?

What is the purpose of Vue adopting the virtual DOM?

It starts with the early days of front-end development.

HTML is a structured text Document. Each element corresponds to a section of structured text in HTML. DOM (Document Object Model) can be understood as an abstraction of this section of structured text.

The DOM is stored in memory and provides a set of apis for manipulating and modifying HTML elements.

DOM manipulation is the core of front-end development. Most of the earliest popular front-end frameworks and tool libraries are famous for their excellent DOM manipulation, such as Prototype.js and jquery.js.

Compared with JavaScript logic, the performance consumption of DOM operations is very high, and the performance loss of small DOM operations is basically negligible in the WebPage era with static content dominant. However, for WebApps with rich dynamic content, a large number of frequent DOM operations gradually become a performance bottleneck.

As far as JavaScript is concerned, the virtual DOM is just an object with rich properties, and all DOM operations are mapped as JavaScript object modifications, which naturally perform much better than direct DOM operations.

The introduction of the virtual DOM also brings the following benefits:

1. Components are highly abstract.

2. Cross-platform capabilities: Render to platforms outside the DOM.

Reference books

In-depth Practical Vue Development by Yin Ronghui

Front-end Technology Architecture and Engineering, Junpeng Zhou