vue组件的重新渲染的问题

文章讲述了在Vue中如何通过修改组件的`key`属性和使用`v-if`指令实现组件的局部或全部重新渲染,重点讲解了`key`在虚拟DOM比较中的作用以及如何在对话框上传组件中利用这些策略提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.方式1

2.方式2


1.方式1

修改组件上的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组件会重新渲染。

2.方式2

使用v-if指令

当DOM设置为false的时候,当前条件块中的DOM会被销毁。如果条件块包含的是组件,则组件对应的生命周期函数(beforeDestroy、destroyed等)会执行。
当DOM设置为true的时候,当前条件块中的DOM会被重建。如果条件块包含的是组件,则组件对应的生命周期函数(created、mounted等),计算属性,watch等都会执行,相当于重新渲染。

参照:

Vue - 组件重新渲染的两种方式_vue重新渲染dom-CSDN博客

Vue 中 强制组件重新渲染的正确方法_forceupdate-CSDN博客

### 如何在 Arco Design 中阻止 PopConfirm 组件的事件传递 在前端开发中,事件冒泡是一个常见的问题,尤其是在处理复杂交互组件时。对于 Arco Design 的 `PopConfirm` 组件,可以通过特定的方式阻止其内部事件向外传播。 #### 方法一:通过 `stopPropagation` 阻止事件冒泡 当使用 `PopConfirm` 组件时,可以绑定一个点击事件处理器,在该处理器中调用 `event.stopPropagation()` 来防止事件继续向父级元素传播[^1]。 以下是实现代码示例: ```javascript function handleStopPropagation(event) { event.stopPropagation(); } <template> <a-pop-confirm title="Are you sure?" ok-text="Yes" cancel-text="No"> <button @click="handleStopPropagation">Click Me</button> </a-pop-confirm> </template> ``` 上述代码片段展示了如何通过监听按钮的点击事件并调用 `stopPropagation` 方法来阻断事件冒泡行为[^2]。 #### 方法二:利用自定义图标与事件拦截 如果需要更复杂的控制逻辑,比如结合 `upload` 或其他子组件的功能,则可考虑使用 `custom-icon` 属性配合事件拦截机制。例如,在上传文件场景下,可通过设置 `on-before-remove` 并返回 `false` 实现取消默认操作的同时阻止事件冒泡[^3]。 下面是一段基于此思路的实际应用案例: ```vue <script setup> import { defineComponent } from 'vue'; export default defineComponent({ methods: { beforeRemove(file, files) { console.log('Before Remove:', file); this.$message.info('File removal canceled.'); return false; // 取消移除动作 }, stopBubble(e) { e.stopPropagation(); // 手动停止冒泡 } } }); </script> <template> <div class="example-container"> <a-upload :before-remove="beforeRemove"> <a-button>Upload File</a-button> </a-upload> <!-- 使用 custom-icon --> <a-pop-confirm v-on="$listeners" title="Sure to delete?" @visible-change="stopBubble"> <span slot="icon"><exclamation-circle-outlined /></span> Delete Button </a-pop-confirm> </div> </template> ``` 以上代码不仅实现了对 `PopConfirm` 显示隐藏状态变化时的冒泡抑制,还演示了如何集成到更大的上下文中去管理多个关联控件的行为模式。 --- #### 总结 无论是简单的单击事件还是涉及多层嵌套结构的情况,都可以采用适当的技术手段有效解决 Arco Design 中关于 `PopConfirm` 的事件冒泡问题。关键是理解目标 DOM 节点上的具体触发条件以及合理运用框架提供的 API 接口完成定制化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值