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

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

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

[[332579]]

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

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

这节,我们就来做一些之前很少做过或者没做过的:用 key 来让组件重新渲染。

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

  • key 是如何改变组件
  • key 如何与多个子组件一起工作
  • 如何强制子组件自己更新

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

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

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

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

  1. <template> 
  2.   <ComponentToReRender 
  3.     :key="componentKey" 
  4.   /> 
  5. </template> 
  6.  
  7. <script> 
  8.   export default { 
  9.     data() { 
  10.       return { 
  11.         componentKey: 0, 
  12.       }; 
  13.     }, 
  14.     methods: { 
  15.       forceRerender() { 
  16.         this.componentKey += 1; 
  17.       } 
  18.     } 
  19.   } 
  20. </script> 

每次调用forceRerender时,componentKey 的值就会更改。当componentKey 的值发生改变时,Vue 就知道把ComponentToReRender组件删除并创建一个新组件。

这样ComponentToReRender就会重新渲染并重置里面的状态。nice nice!

强制多个子节点进行更新

同样用这种方式也可以用于多个子组件:

  1. <template> 
  2.   <div> 
  3.     <Child 
  4.       :key="key1" 
  5.     /> 
  6.     <Child 
  7.       :key="key2" 
  8.     /> 
  9.   </div> 
  10. </template> 
  11.  
  12. <script> 
  13.   export default { 
  14.     data() { 
  15.       return { 
  16.         key1: 0, 
  17.         key2: 0, 
  18.       }; 
  19.     }, 
  20.     methods: { 
  21.       forceRerender(child) { 
  22.         if (child === 1) { 
  23.           this.key1 += 1; 
  24.         } else if( child === 2) { 
  25.           this.key2 += 1; 
  26.         } 
  27.       } 
  28.     } 
  29.   } 
  30. </script> 

这里我们使用了两个单独 key 来分别控制每个子组件是否重新渲染。将它们分开是为了其中的一个子组件渲染,不会影响到另外另一个。

但如果希望两个子组件总是一起更新,则可以使用相同的 kye。但是,key必须是唯一的,所以下面这种方式,不能工作:

  1. <template> 
  2.   <div> 
  3.     <Child 
  4.       :key="componentKey" 
  5.     /> 
  6.     <Child 
  7.       :key="componentKey" 
  8.     /> 
  9.   </div> 
  10. </template> 
  11.  
  12. <script> 
  13.   export default { 
  14.     data() { 
  15.       return { 
  16.         componentKey: 0, 
  17.       }; 
  18.     }, 
  19.     methods: { 
  20.       forceRerender(child) { 
  21.         this.componentKey += 1; 
  22.       } 
  23.     } 
  24.   } 
  25. </script> 

在这里,仅第一个Child组件会被渲染。第二个被忽略,因为它具有重复的key 了。

为了解决这个问题,我们可以基于componentKey为每个孩子构造一个新key:

  1. <template> 
  2.   <div> 
  3.     <Child 
  4.       :key="`${componentKey}-1`" 
  5.     /> 
  6.     <Child 
  7.       :key="`${componentKey}-2`" 
  8.     /> 
  9.   </div> 
  10. </template> 
  11.  
  12. <script> 
  13.   export default { 
  14.     data() { 
  15.       return { 
  16.         componentKey: 0, 
  17.       }; 
  18.     }, 
  19.     methods: { 
  20.       forceRerender(child) { 
  21.         this.componentKey += 1; 
  22.       } 
  23.     } 
  24.   } 
  25. </script> 

因为我们每次在componentKey后面添加-1和-2,所以这两个key始终是唯一的,现在这两个组件都将被重新渲染。

如果是在列表中,则可以使用如下方式:

  1. <template> 
  2.   <div> 
  3.     <Child 
  4.       v-for="(item, index) in list" 
  5.       :key="`${componentKey}-${index}`" 
  6.     /> 
  7.   </div> 
  8. </template> 
  9.  
  10. <script> 
  11.   export default { 
  12.     data() { 
  13.       return { 
  14.         list: [ 
  15.           // ... 
  16.         ], 
  17.         componentKey: 0, 
  18.       }; 
  19.     }, 
  20.     methods: { 
  21.       forceRerender(child) { 
  22.         this.componentKey += 1; 
  23.       } 
  24.     } 
  25.   } 
  26. </script> 

在这里,我们将key构造为${componentKey}-${index},因此列表中的每个项目都会获得唯一的key,只要componentKey一改变,列表中的所有组件将同时重新渲染。

当然,还有更简单的方式,就是用div把列表包裹起来,直接对 div重新更新就行了:

  1. <template> 
  2.   <div :key="componentKey"
  3.     <Child 
  4.       v-for="item in list" 
  5.       :key="item.id" 
  6.     /> 
  7.   </div> 
  8. </template> 
  9.  
  10. <script> 
  11.   export default { 
  12.     data() { 
  13.       return { 
  14.         list: [ 
  15.           // ... 
  16.         ], 
  17.         componentKey: 0, 
  18.       }; 
  19.     }, 
  20.     methods: { 
  21.       forceRerender(child) { 
  22.         this.componentKey += 1; 
  23.       } 
  24.     } 
  25.   } 
  26. </script> 

这中思路可以用在很多地方,可以为我们摆脱很的困境,大家要牢记起来。

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

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

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

本文转载自微信公众号「大迁世界」,可以通过以下二维码关注。转载本文请联系大迁世界公众号。

 

责任编辑:武晓燕 来源: 大迁世界
相关推荐

2020-06-29 08:28:36

v-for 解构函数

2020-07-14 08:43:54

VueHTML函数

2021-01-15 05:39:13

HashMapHashTableTreeMap

2015-07-22 11:53:29

云计算AWS分析瘫痪

2020-07-01 08:36:43

CSS规范web

2021-08-24 00:13:23

Windows 10Windows微软

2022-12-05 15:23:33

JavaScript技巧运算符

2019-01-07 09:27:39

2021-08-27 10:03:12

人工智能AI

2020-11-20 06:13:04

Like %

2018-08-10 10:36:25

SSL证书误区

2019-12-13 19:52:29

人工智能AI

2021-08-08 21:53:40

Arthas指令表达式

2023-06-05 08:07:34

聚集索引存储数据

2021-01-12 12:33:20

Pandas技巧代码

2024-09-12 08:32:42

2022-07-06 10:33:39

技术债务CIO

2021-11-02 19:14:58

Spring数据

2021-01-07 05:27:20

包导入变量

2021-05-08 23:19:25

微信存储小程序
点赞
收藏

51CTO技术栈公众号