最近遇到的有点神奇的bug
- 父组件切换
tab
时,走了handleTabChange
函数,发布事件
js
<template>
<PostList :type="activeTab" :key="activeTab"/>
</template>
<script setup>
import emitter from "~/src/utils/eventBus";
const activeTab = ref('all');
const handleTabChange = (tab) => {
activeTab.value = tab;
// 发布事件
emitter.emit("articleParamsChanged", {
type: tab,
});
};
// 父组件
onMounted(() => {
// 发送初始参数事件
emitter.emit("articleParamsChanged", {
type: activeTab.value,
});
});
</script>
- 子组件接收事件后,刷新列表,模版里面list是[]
js
<template>
<PostItem v-for="item in articleList" :item="item" :key="item.id" />
</template>
<script setup>
import PostItem from "./PostItem.vue";
import { fetchList } from "@/api/app/index";
import emitter from "~/src/utils/eventBus";
const list = ref([]) // 列表
const pageNum = ref(1);
const pageSize = ref(5);
// 获取文章列表
const getList = async (isLoadMore = false) => {
if (!isLoadMore) list.value = [];
loading.value = true;
try {
// 请求参数
const requestData = {
page: pageNum.value,
page_size: pageSize.value,
type: queryParams.value.type,
keyword: queryParams.value.searchValue,
};
const res = await fetchList(requestData);
list.value = [...list.value, ...res.data.articles];
console.log(list.value,'切换tab之后的list更新了')
articleTotal.value = res.data.total;
} catch (err) {
console.log(err);
} finally {
loading.value = false;
}
};
// 处理父组件参数变化事件
const handleParamsChanged = (params) => {
Object.assign(queryParams.value, params);
pageNum.value = 1;
getList();
};
onMounted(() => {
// 订阅
emitter.on("articleParamsChanged", handleParamsChanged);
});
</script>
分析
- 怀疑
list
数组没有重新更新,通过打印发现,数据已更新; - 刚开始怀疑
list
响应式丢失,通过在Vue DevTool
中查看发现list还具有响应式; - 最后发现父组件调用子组件
PostList
上有key
,去掉key
问题解决。
解决方法
删除key
js
// 父组件
<template>
<PostList :type="activeTab" />
</template>
思考:为什么去掉key
问题解决?
父组件先发送的emitter
,然后因为key
销毁重建子组件了,之后没在发送emitter
,导致子组件出现list=[]
,去掉key
则不会销毁重建子组件。