目录
修改组件上的key属性
Vue是通过diffing算法比较虚拟DOM和真实DOM,来判断新旧 DOM 的变化。key是虚拟DOM对象的标识,在更新显示时key表示着DOM的唯一性。
DOM是否变化的核心是通过判断新旧DOM的key值是否变化,如果key发生改变,则重新渲染该DOM,如果key没变,则不会重新DOM。
如果想让组件重新渲染,只需要给组件加上key属性,然后在需要重新渲染的时候,将组件绑定的key值更改就可以。
- <div class="item" v-for="(item, index) in list" :key="item.id">
- <child :id="item" :key="key"></child>
- </div>
比如常见的v-for指令会经常使用到key属性,key属性内容一般使用id,因为id是唯一的。当list的内容发生变化时,vue会进行比较,key值没有变化的则不会渲染,只有key值变换的才会进行局部的渲染,这样避免了list发生了变化,整个列表都要重新渲染的问题,所有通过key属性的使用提高了性能。
所以说,如果想重新渲染组件时,只需要改变key属性即可。
例如对话框中的上传组件,每次打开需要重新渲染,避免保留上次上传的文件信息。
- <template>
- <a-modal :visible="visiable" :title="title" @ok="handleOk" @cancel="handleCancel" :ok-loading="okLoad" >
- <a-upload draggable accept=".xlsx" :custom-request="customRequest" :limit='1' :key="KeyInfo"/>
- </a-modal>
- </template>
- <script lang="ts" setup>
- import {importInfo, dowload} from '@/api/upload';
- import {Message} from '@arco-design/web-vue';
- import moment from "moment"
- import {ref} from 'vue'
-
-
- const prop = defineProps({
- title: String,
- params: String,
- })
- const visiable = ref(false);
-
- const okLoad = ref(false)
-
- const KeyInfo = ref(Math.random());
-
- let fileInfo:any = {}
- // 自定义上传事件
- const customRequest = (option: any) => {
- const {onProgress, onError, onSuccess, fileItem, name} = option
- fileInfo = fileItem;
- onSuccess()
- console.log("上传文件信息:" + JSON.stringify(fileInfo))
- }
-
- const emit = defineEmits(['handleQuery'])
-
- const open = () => {
- visiable.value = true
- KeyInfo.value = Math.random()
- }
- // 导出方法在父组件中进行使用
- defineExpose({open});
-
- // 关闭弹框
- const handleCancel = () => {
- visiable.value = false
- KeyInfo.value = Math.random()
- }
- // 确定事件
- const handleOk = async () => {
- okLoad.value = true;
- // 上传文件不能为空
- if(!fileInfo.name){
- Message.error({content:'上传的文件不能为空',position:'top'})
- okLoad.value = false;
- return
- }
- try {
- let formData = new FormData()
- formData.set('file', fileInfo.file)
- formData.set('data', prop.params ? prop.params : '')
- const res = await importInfo(formData)
- if (res == '1') {
- Message.success({content: '操作成功', position: 'top'});
- } else {
- Message.error({content: '导入的文件中存在重复,重复的地点信息请参照下载的文件', position: 'top'});
- await dowload('/em/file/mb1002', '', `地点信息_${moment().format('yyyyMMDDHHmmss')}.xlsx`, {})
- }
- visiable.value = false
- emit('handleQuery')
- fileInfo = {}
- KeyInfo.value = Math.random()
- } catch (e) {
- console.log(e)
- } finally {
- okLoad.value = false;
- }
- }
- </script>
在upload组件中追加了key属性, 组件第一次加载时,key的内容为随机数,打开时设置为随机数。这样每次打开时,key变化了,所以upload组件会重新渲染。
使用v-if指令
当DOM设置为false的时候,当前条件块中的DOM会被销毁。如果条件块包含的是组件,则组件对应的生命周期函数(beforeDestroy、destroyed等)会执行。
当DOM设置为true的时候,当前条件块中的DOM会被重建。如果条件块包含的是组件,则组件对应的生命周期函数(created、mounted等),计算属性,watch等都会执行,相当于重新渲染。
参照: