Vue でコンポーネントを正しく強制的に再レン​​ダリングするにはどうすればよいですか? (手法の紹介)

青灯夜游
リリース: 2020-06-24 14:12:27
転載
17693 人が閲覧しました

Vue でコンポーネントを正しく強制的に再レン​​ダリングするにはどうすればよいですか? (手法の紹介)

Vue の応答性に頼ってデータを更新するだけでは不十分な場合があり、代わりにコンポーネントを手動で再レンダリングしてデータを更新する必要があります。あるいは、現在の DOM を破棄して最初からやり直すこともできます。では、Vue でコンポーネントを正しい方法で再レンダリングするにはどうすればよいでしょうか?

Vue にコンポーネントの再レンダリングを強制する最良の方法は、コンポーネントに :key を設定することです。コンポーネントを再レンダリングする必要がある場合、key の値を変更するだけで、Vue がコンポーネントを再レンダリングします。

これは非常に簡単な解決策です。

もちろん、他の方法に興味があるかもしれません:

  • 単純で大雑把な方法: ページ全体をリロードする
  • 不適切な方法: usev -if
  • より良い方法: Vue の組み込み forceUpdate メソッドを使用します
  • 最適な方法: コンポーネントの キー Change

簡単で大雑把な方法: ページ全体をリロードします。

これは、コンピュータを毎回再起動するたびにアプリケーションを閉じるのと同じです。 。

Vue でコンポーネントを正しく強制的に再レン​​ダリングするにはどうすればよいですか? (手法の紹介)

この方法は機能するかもしれませんが、非常に悪い解決策です。これは行わないでください。見てみましょう。もっといい方法。

不適切な方法: v-if

v- if# を使用します## ディレクティブ。コンポーネントが true の場合にのみレンダリングされます。 false の場合、コンポーネントは DOM に存在しません。

v-if がどのように機能するかを見てみましょう。template に、v-if ディレクティブを追加します:

<template>
  <my-component v-if="renderComponent" />
</template>
ログイン後にコピー

In

scriptnextTick メソッドを使用します

<script>
  export default {
    data() {
      return {
        renderComponent: true,
      };
    },
    methods: {
      forceRerender() {
        // 从 DOM 中删除 my-component 组件
        this.renderComponent = false;
        
        this.$nextTick(() => {
          // 在 DOM 中添加 my-component 组件
          this.renderComponent = true;
        });
      }
    }
  };
</script>
ログイン後にコピー

上記のプロセスは大まかに次のとおりです:

    Just starting
  1. renderComponent true に設定されているため、my-component コンポーネント
  2. をレンダリングすると、
  3. forceRerender を呼び出すと、すぐに renderComponentfalse
  4. に設定されています。
  5. v-if ディレクティブが false と評価されるため、my-component のレンダリングを停止します。
  6. v-if When の場合、nextTick メソッドで renderComponenttrue
  7. に設定します。命令の計算結果は truemy-component を再度レンダリングします
  8. ##このプロセスには、より重要な部分が 2 つあります

まず、

nextTick

まで待つ必要があります。そうしないと、変更が表示されません。

Vue

では、ティックは DOM 更新サイクルを表します。 Vue は同じティック内で行われたすべての更新を収集し、ティックの終了時にそれらの更新に基づいて DOM 内のコンテンツをレンダリングします。次のティックまで待たないと、renderComponent への更新は自動的にキャンセルされ、何も変わりません。 2 番目に、2 回目のレンダリング時に、Vue はまったく新しいコンポーネントを作成します。 Vue は最初のコンポーネントを破棄し、新しいコンポーネントを作成します。これは、新しい

my-component

が通常どおりすべてのライフサイクルを通過することを意味します - created Mounted また、

nextTick

は、promise とともに使用できます: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">forceRerender() { // 从 DOM 中删除 my-component 组件 this.renderComponent = false; this.$nextTick().then(() =&gt; { this.renderComponent = true; }); }</pre><div class="contentsignin">ログイン後にコピー</div></div> ただし、これはあまり良い解決策ではないので、Vue が望んでいることを実行しましょう。

## より良い方法:forceUpdate メソッド

これは、この問題を解決する 2 つの最良の方法のうちの 1 つであり、どちらの方法もすべて Vue で正式にサポートされています。

通常、Vue はビューを更新することで依存関係の変更に対応します。ただし、

forceUpdate

を呼び出すと、すべての依存関係が実際には変更されていない場合でも、更新を強制することもできます。

この方法を使用するときにほとんどの人が犯す最大の間違いは次のとおりです。

Vue が状況に変化があったときに自動的に更新するのであれば、なぜ強制的に更新する必要があるのでしょうか?

その理由は、Vue の応答システムが混乱を招く場合があるためです。Vue は特定のプロパティまたは変数の変更に応答すると考えられていますが、実際にはそうではありません。場合によっては、Vue のリアクティブ システムが変更をまったく検出しないことがあります。

したがって、前の方法と同様に、コンポーネントを再レンダリングするためにこれが必要な場合は、おそらくもっと良い方法があるでしょう。

コンポーネント インスタンス自体とグローバルの両方で、

forceUpdate

を呼び出すことができる 2 つの異なるメソッドがあります:

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

// 使用组件实例
export default {
  methods: {
    methodThatForcesUpdate() {
      // ...
      this.$forceUpdate();
      // ...
    }
  }
}
ログイン後にコピー
重要な注意: これは、次の計算プロパティを更新しません。 call forceUpdate

はビューの再レンダリングを強制するだけです。

最良の方法: コンポーネントで

key を変更します多くの場合次へ、コンポーネントを再レンダリングする必要があります。

要正确地做到这一点,我们将提供一个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 },
];
ログイン後にコピー

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

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

// Outputs
Evan - 0
Sarah - 1
James - 2
ログイン後にコピー

如果删除Sarah,得到:

Evan - 0
James - 1
ログイン後にコピー

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>
ログイン後にコピー

在我们从列表中删除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;  
    }
  }
}
ログイン後にコピー

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

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

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

推荐学习:vue视频教程

以上がVue でコンポーネントを正しく強制的に再レン​​ダリングするにはどうすればよいですか? (手法の紹介)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート