您的位置:首页 > Web前端 > Vue.js

很多人不知道可以使用这种 key 的方式来对 Vue 组件进行重新渲染!

2020-07-12 16:27 253 查看

在某些情况下,我们必须强制Vue重新渲染组件,如果没有,那可能,你做的业务还不够负责,反正我是经常需要重新渲染组件,哈哈。

虽然Vue不会自动更新这种情况是相对比较少,但是知道如何在出现这个问题时修复它还是很有用的。

在大多数情况下,此问题根源还是我们对 Vue 的响应式理解还是不够到位。因此,要尽量确保我们要正确使用了Vue。响应式有时过于棘手,我也经常不知道所措。

这节,我们就来做一些之前很少做过或者没做过的:用

key
 来让组件重新渲染。

在这篇文章中,会涉及到这几个知识点:

  • key 是如何改变组件

  • key 如何与多个子组件一起工作

  • 如何强制子组件自己更新

通过改变
key
的值来重新渲染组件

我最喜欢的方法是使用

key
属性,因为使用
key
的方式,Vue 就知道了特定组件与特定数据相关。

如果

key
保持不变,则不会更改组件。但是,如果
key
发生更改, Vue 知道它应该删除旧组件并创建一个新组件。

下面是一个非常基本的方法:

<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>
这中思路可以用在很多地方,可以为我们摆脱很的困境,大家要牢记起来。

好了,今天就跟大家分享到这里,我们下期在见,谢谢大家的观看。

作者:Michael Thiessen  译者:前端小智  来源:medium

原文:https://morioh.com/p/08963bf07353

相关热门推荐

前端如何提高用户体验:增强可点击区域的大小

周末学会了 10个超级实用 Javascript 技巧!

CSS Viewport 单位,很多人还不知道使用它来快速布局!

30 个纯 HTML5 实现的游戏

很多人不知道 v-for 可以这样解构

小智最近在学习正则,学习过程中发现这 6 个方便的正则表达式

详解 ES10 中 Object.fromEntries() 的缘起

有哪些被低估未被广泛使用的有用的 HTML标签?

【干货】工业软件为什么这么难?

JS执行上下文的两个阶段做了些啥?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐