很多人不知道可以使用这种 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
相关热门推荐
CSS Viewport 单位,很多人还不知道使用它来快速布局!
小智最近在学习正则,学习过程中发现这 6 个方便的正则表达式
相关文章推荐
- vue使用prop可以渲染但是打印台报错的解决方式
- Vue.js父与子组件之间传参 父向子组件传参 例子:App.vue为父,引入componetA组件之后,则可以在template中使用标签(注意驼峰写法要改成componet-a写法,因为ht
- ios中的开发一些小工具(就是一个写UIView的自定义组件的脱离环境,可以重新使用)解耦
- 使用Vue开发网站之路2-多组件通信1(利用bus总线进行事件触发)
- vue2.3.0+使用.sync修饰符对prop进行双向绑定/子组件同步prop到父组件绑定的值
- Vue 中可以定义组件模版的几种方式
- 使用Delphi的Socket组件进行阻塞方式通信的零碎
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- vue 2 使用Bus.js进行兄弟(非父子)组件通信 简单案例
- vue中组件的3种使用方式详解
- vue html 动态渲染组件几种方法(使用vue-qrcode 生成二维码)
- 2.服务端拦截器:这种发布方式,拦截器可以正常使用
- 在MAC上安装软件,可能不是来自官方的软件,这时需要对来源进行选择,可以使用以下方式打开
- 在使用MyEclipse新建文件时常常有些不需要的冗余代码可以采用如下方式进行更改
- 使用vue开发输入型组件更好的一种解决方式(子组件向父组件传值,基于2.2.0)
- 今天无意中发现JavaBean类基本都要求实现了Serializable接口,以前只是知道序列化以后,可以通过io流的方式将对象序列化和反序列化,进行存取,但不知道为什么需要序列化,今天总结一下
- 在项目中使用SmartUpload组件可以进行文件的上传和下载操作
- Vue单文件组件的如何使用方式介绍
- 编译时向内核添加新设备 模块的方式动态的将驱动加入内核,但这种方式加入的驱动程序,当系统重新启动时, 还需要重新用模块的方式进行插入,如果是系统内常用的设备驱动采用这种方式进行加载, 就会很不方便。