vue 同一页面引用多个重复组件,但不同组件内的数据感觉是混乱的,请问怎么解决?
问题背景
先贴个图说一下我的页面布局:
如上图,页面中有 5 个重复的子组件,当在某一个组件中点击白色上传区域并选择文件后,对应操作的子组件的白色上传区域会展示当前选中的文件名。
发现问题
现在有个很奇怪的问题是,不管我点击哪一个子组件的白色上传区域,最后选了文件后,文件名都会展示在第一个组件中。明明每个组件的数据是隔离的,这里为啥会这样呢?有点不太理解。
代码片段
父组件
<template>
<div class="grid gap-0 grid-cols-4 grid-rows-2 h-full pb-8">
<Card title="导入项目排名" type="projectRank"></Card>
<Card title="导入申请书初审结果" type="projectFirstTrial"></Card>
<Card title="导入申请书终审结果" type="projectFinalTrial"></Card>
<Card title="导入实施方案终审结果" type="executeFinalTrial"></Card>
<Card title="导入机构对项目的评分" type="projectScore"></Card>
</div>
</template>
<script setup lang="ts">
import Card from "@/components/importDataCard.vue";
</script>
子组件有两个属性,由父组件传入。
子组件
<template>
//子组件的 template 不止这些,为了给大家减轻阅读负担,我只贴了核心部分
<div class="w-full h-full">
<div class="mb-6">
<div class="flex flex-col justify-center items-center w-full h-32">
<label :for="file ? '' : 'file-input'">
<div class="flex flex-col justify-center items-center pt-5 pb-6">
<template v-if="file">
<p class="mb-2 text-sm relative text-gray-500 dark:text-gray-400">{{ file.name }}</p>
</template>
<template v-else>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400">点击上传或拖拽文件到此处</p>
<p class="text-xs font-extralight text-gray-500 dark:text-gray-400">仅支持 CSV</p>
</template>
</div>
<input id="file-input" type="file" class="hidden" @change="setFile" accept=".csv"/>
</label>
</div>
</div>
<div class="mb-6">
<button type="button">导入数据</button>
</div>
</div>
</template>
<script setup lang="ts">
import {ref, defineProps} from 'vue';
const props = defineProps({
type: String,
title: String
})
const file = ref<File|null>(null)
function setFile(e) {
file.value = e.target.files[0]
}
</script>
以上就是所有的问题描述,请各位前端大佬分析分析,到底怎么回事呢?
问题解决了,这个问题跟 vue 没有半毛钱关系。在 vue 中创建多个相同子组件,他都有独立且完整的生命周期,并且变量都是隔离的。
下面且说这问题出哪了。
大家看到有一句
<label :for="file ? '' : 'file-input'">
,这个label
标签就指定了白色的上传区域,当file
未被设置时,这个for
属性是一个固定值file-input
。下面还有这么一句
<input id="file-input" type="file" class="hidden" @change="setFile"
,这是最终接收文件的 input 输入框,他的id
刚好就是上边label
指定的 id 值。问题就在于,在一个 DOM 树中,元素的
id
是独一无二的,我的组件有 5 个,都是同样的 ID,就造成了上述奇葩问题。做了如下修改:错误:
正确:
注: 以上是把固定的 ID 值替换成了变量
type
,这个变量即 props 属性之一,在上面的子组件代码中有定义。记录一下,希望帮到需要的小伙伴。