Home > Web Front-end > JS Tutorial > body text

How to correctly force components to re-render in Vue? (Method introduction)

青灯夜游
Release: 2020-06-24 14:12:27
forward
17688 people have browsed it

How to correctly force components to re-render in Vue? (Method introduction)

Sometimes, relying on Vue's responsiveness to update data is not enough. Instead, we need to manually re-render the component to update data. Or, we might just want to throw away the current DOM and start over. So, how do you get Vue to re-render the component in the correct way?

The best way to force Vue to re-render a component is to set :key on the component. When we need to re-render the component, we only need to change the value of key, and Vue will re-render the component.

This is a very simple solution.

Of course, you may be more interested in other ways:

  • Simple and crude way: reload the entire page
  • Inappropriate way: usev-if
  • Better method: Use Vue’s built-in forceUpdate method
  • Best method: key on the component Change

Easy and crude way: reload the entire page

This is equivalent to closing the application every time you want to Restart your computer every time.

How to correctly force components to re-render in Vue? (Method introduction)

This method may work, but it is a very bad solution, Don’t do this, let’s see See a better way.

Inappropriate way: use v-if

v- if directive, which only renders when the component is true. If false, the component does not exist in DOM.

Let’s see how v-if works. In template, add the v-if directive:

<template>
  <my-component v-if="renderComponent" />
</template>
Copy after login

In script, use the nextTick method

<script>
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // 从 DOM 中删除 my-component 组件
        this.renderComponent = false;
        
        this.$nextTick(() => {
          // 在 DOM 中添加 my-component 组件
          this.renderComponent = true;
        });
      }
    }
  };
</script>
Copy after login

The above process is roughly as follows:

  1. Just started renderComponent is set to true, so rendering my-component component
  2. when we call forceRerender, we immediately renderComponent is set to false
  3. We stop rendering my-component because the v-if directive now evaluates to false
  4. Set renderComponent back to true in the
  5. nextTick
  6. method when v-if When the calculation result of the instruction is true, render my-component again
##In this process, there are two parts that are more important

First, we have to wait until

nextTick, otherwise we won't see any changes.

In

Vue, a tick is a DOM update cycle. Vue will collect all updates made in the same tick, and at the end of the tick it will render the content in the DOM based on those updates. If we don't wait until the next tick, our update to renderComponent will be automatically canceled and nothing will change.

Secondly, when we render for the second time, Vue will create a brand new component. Vue will destroy the first one, and create a new one, which means our new

my-component will go through all its lifecycle like normal - created, mountedetc.

Also,

nextTick can be used with promise:

forceRerender() {
  // 从 DOM 中删除 my-component 组件
  this.renderComponent = false;

  this.$nextTick().then(() => {
    this.renderComponent = true;
  });
}
Copy after login

However, this is not a very good solution, so, let's do what Vue wants us to do The

Better method: forceUpdate method

This is one of the two best ways to solve this problem, both methods All are officially supported by Vue.

Normally, Vue responds to changes in dependencies by updating views. However, when we call

forceUpdate, it is also possible to force an update even if all dependencies have not actually changed.

Here are the biggest mistakes most people make when using this method.

If Vue automatically updates when things change, why do we need to force an update?

The reason is that sometimes Vue's response system can be confusing. We think that Vue will respond to changes in a certain property or variable, but in fact this is not the case. In some cases, Vue's reactive system detects no changes at all.

So like the previous method, if you need this to re-render your component, there's probably a better way.

There are two different methods that can be called

forceUpdate, both on the component instance itself and globally:

// 全局
import Vue from &#39;vue&#39;;
Vue.forceUpdate();

// 使用组件实例
export default {
  methods: {
    methodThatForcesUpdate() {
      // ...
      this.$forceUpdate();
      // ...
    }
  }
}
Copy after login

Important note: This will not update any computed properties that call

forceUpdate only forces the view to be re-rendered.

The best way: make key changes on the component

In many cases Next, we need to re-render the component.

要正确地做到这一点,我们将提供一个key属性,以便 Vue 知道特定的组件与特定的数据片段相关联。如果key保持不变,则不会更改组件,但是如果key发生更改,Vue 就会知道应该删除旧组件并创建新组件。

正是我们需要的!

但是首先,我们需要绕一小段路来理解为什么在Vue中使用key

为什么我们需要在 Vue 中使用 key

一旦你理解了这一点,那么这是了解如何以正确方式强制重新渲染的很小的一步。

假设我们要渲染具有以下一项或多项内容的组件列表:

  • 有本地的状态
  • 某种初始化过程,通常在createdmounted钩子中
  • 通过jQuery或普通api进行无响应的DOM操作

如果你对该列表进行排序或以任何其他方式对其进行更新,则需要重新渲染列表的某些部分。 但是,不会希望重新渲染列表中的所有内容,而只是重新渲染已更改的内容。

为了帮助 Vue 跟踪已更改和未更改的内容,我们提供了一个key属性。 在这里使用数组的索引,因为索引没有绑定到列表中的特定对象。

const people = [
  { name: &#39;Evan&#39;, age: 34 },
  { name: &#39;Sarah&#39;, age: 98 },
  { name: &#39;James&#39;, age: 45 },
];
Copy after login

如果我们使用索引将其渲染出来,则会得到以下结果:

<ul>
  <li v-for="(person, index) in people" :key="index">
    {{ person.name }} - {{ index }}
  </li>
</ul>

// Outputs
Evan - 0
Sarah - 1
James - 2
Copy after login

如果删除Sarah,得到:

Evan - 0
James - 1
Copy after login

James关联的索引被更改,即使James仍然是JamesJames会被重新渲染,这并不是我们希望的。

所以这里,我们可以使用唯一的 id 来作为 key

const people = [
  { id: &#39;this-is-an-id&#39;, name: &#39;Evan&#39;, age: 34 },
  { id: &#39;unique-id&#39;, name: &#39;Sarah&#39;, age: 98 },
  { id: &#39;another-unique-id&#39;, name: &#39;James&#39;, age: 45 },
];

<ul>
  <li v-for="person in people" :key="person.id">
    {{ person.name }} - {{ person.id }}
  </li>
</ul>
Copy after login

在我们从列表中删除Sarah之前,Vue删除了SarahJames的组件,然后为James创建了一个新组件。现在,Vue知道它可以为EvanJames保留这两个组件,它所要做的就是删除Sarah的。

如果我们向列表中添加一个person,Vue 还知道可以保留所有现有的组件,并且只需要创建一个新组件并将其插入正确的位置。这是非常有用的,当我们有更复杂的组件,它们有自己的状态,有初始化逻辑,或者做任何类型的DOM操作时,这对我们很有帮助。

所以接下来看看,如果使用最好的方法来重新渲染组件。

更改 key 以强制重新渲染组件

最后,这是强制Vue重新渲染组件的最佳方法(我认为)。

我们可以采用这种将key分配给子组件的策略,但是每次想重新渲染组件时,只需更新该key即可。

这是一个非常基本的方法

<template>
  <component-to-re-render :key="componentKey" />
</template>


export default {
  data() {
    return {
      componentKey: 0,
    };
  },
  methods: {
    forceRerender() {
      this.componentKey += 1;  
    }
  }
}
Copy after login

每次forceRerender被调用时,我们的componentKey都会改变。当这种情况发生时,Vue将知道它必须销毁组件并创建一个新组件。我们得到的是一个子组件,它将重新初始化自身并“重置”其状态。

如果确实需要重新渲染某些内容,请选择key更改方法而不是其他方法。

原文地址:https://hackernoon.com/the-correct-way-to-force-vue-to-re-render-a-component-bde2caae34ad

推荐学习:vue视频教程

The above is the detailed content of How to correctly force components to re-render in Vue? (Method introduction). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template