不少人不知道可使用這種 key 的方式來對 Vue 組件時行從新渲染!

做者:Michael Thiessen 譯者:前端小智 來源:medium前端

點贊再看,養成習慣git

本文 GitHub github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。github

在某些狀況下,咱們必須強制Vue從新渲染組件,若是沒有,那可能,你作的業務還不夠負責,反正我是常常須要從新渲染組件,哈哈。面試

雖然Vue不會自動更新這種狀況是相對比較少,可是知道如何在出現這個問題時修復它仍是頗有用的。bash

在大多數狀況下,此問題根源仍是咱們對 Vue 的響應式理解仍是不夠到位。 所以,要儘可能確保咱們要正確使用了Vue。 響應式有時過於棘手,我也常常不知道所措。微信

這節,咱們就來作一些以前不多作過或者沒作過的:用 key 來讓組件從新渲染。工具

在這篇文章中,會涉及到這幾個知識點:ui

  • key 是如何改變組件
  • key 如何與多個子組件一塊兒工做
  • 如何強制子組件本身更新

經過改變 key 的值來從新渲染組件

我最喜歡的方法是使用key屬性,由於使用key 的方式,Vue 就知道了特定組件與特定數據相關。this

若是 key保持不變,則不會更改組件。 可是,若是key發生更改, Vue 知道它應該刪除舊組件並建立一個新組件。spa

下面是一個很是基本的方法:

<template>
  <ComponentToReRender
    :key="componentKey"
  />
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender() {
        this.componentKey += 1;
      }
    }
  }
</script>
複製代碼

每次調用forceRerender時,componentKey 的值就會更改。 當componentKey 的值發生改變時,Vue 就知道把ComponentToReRender組件刪除並建立一個新組件。

這樣ComponentToReRender就會從新渲染並重置裏面的狀態。nice nice!

強制多個子節點進行更新

一樣用這種方式也能夠用於多個子組件:

<template>
  <div>
    <Child
      :key="key1"
    />
    <Child
      :key="key2"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        key1: 0,
        key2: 0,
      };
    },
    methods: {
      forceRerender(child) {
        if (child === 1) {
          this.key1 += 1;
        } else if( child === 2) {
          this.key2 += 1;
        }
      }
    }
  }
</script>
複製代碼

這裏咱們使用了兩個單獨 key 來分別控制每一個子組件是否從新渲染。將它們分開是爲了其中的一個子組件渲染,不會影響到另外另外一個。

但若是但願兩個子組件老是一塊兒更新,則可使用相同的 kye。可是,key必須是惟一的,因此下面這種方式,不能工做:

<template>
  <div>
    <Child
      :key="componentKey"
    />
    <Child
      :key="componentKey"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>
複製代碼

在這裏,僅第一個Child組件會被渲染。 第二個被忽略,由於它具備重複的key 了。

你們都說簡歷沒項目寫,我就幫你們找了一個項目,還附贈【搭建教程】

爲了解決這個問題,咱們能夠基於componentKey爲每一個孩子構造一個新key

<template>
  <div>
    <Child
      :key="`${componentKey}-1`"
    />
    <Child
      :key="`${componentKey}-2`"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>
複製代碼

由於咱們每次在componentKey後面添加-1-2,因此這兩個key始終是惟一的,如今這兩個組件都將被從新渲染。

若是是在列表中,則可使用以下方式:

<template>
  <div>
    <Child
      v-for="(item, index) in list"
      :key="`${componentKey}-${index}`"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        list: [
          // ...
        ],
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>
複製代碼

在這裏,咱們將key構造爲${componentKey}-${index},所以列表中的每一個項目都會得到惟一的key,只要componentKey一改變,列表中的全部組件將同時從新渲染。

固然,還有更簡單的方式,就是用div把列表包裹起來,直接對 div從新更新就好了:

<template>
  <div :key="componentKey">
    <Child
      v-for="item in list"
      :key="item.id"
    />
  </div>
</template>

<script>
  export default {
    data() {
      return {
        list: [
          // ...
        ],
        componentKey: 0,
      };
    },
    methods: {
      forceRerender(child) {
        this.componentKey += 1;
      }
    }
  }
</script>
複製代碼

這中思路能夠用在不少地方,能夠爲咱們擺脫很的困境,你們要牢記起來。

好了,今天就跟你們分享到這裏,咱們下期在見,謝謝你們的觀看。


代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug

原文:morioh.com/p/08963bf07…


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub github.com/qq449245884… 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索