详解强制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>
这中思路可以用在很多地方,可以为我们摆脱很的困境,大家要牢记起来。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 技术篇-使用opencv读取图片实例演示,python安装opencv库
- 关于页更改并加入一些在线服务
- Hadoop-2.6.0为基础的Hive安装
- Python 技术篇-opencv读取中文路径图片报错及解决办法
- Javaweb鼠标事件案例分析—鼠标移入移出表格颜色变化
- docker registry V2私有仓库搭建
- Python 路径问题:cv2.error: OpenCV(4.1.0)...size.width>0 && size.height>0 in function 'cv::imshow'. 原因与解决
- 算法案例分析—字符串模式匹配算法
- Docker-软件工程集装箱技术
- PyQt5 技术篇-获取电脑屏幕桌面的宽、高和分辨率
- 使用Python快速抠图
- 值得白嫖的数据库常用操作语句汇总(数据库、数据表、数据操作)
- JavaScript 技术篇-js正则表达式匹配字符串左右两边是否包含空格
- 初入编程吓破胆?那是你还不懂这些!(高能预警)
- 振兴杯试题功能设计(准备)