我在vue3中有这个组件:
<template>
<div class="list-cell">
<div
v-for="(value, index) in lines"
ref="items"
:key="index"
class="list-cell--item"
>
{{ value }}
</div>
</div>
</template>
<script setup lang="ts">
import { Ref, ref, onMounted, onUnmounted, PropType } from 'vue';
const items: Ref<HTMLElement[]> = ref([]);
defineProps({
lines: { type: Array as PropType<string[]>, default: () => [] },
});
const handleMouseEnter = () => {
console.log(1);
};
const handleMouseLeave = () => {
console.log(2);
};
onMounted(() => {
items.value.forEach((item) => {
item.addEventListener('mouseenter', handleMouseEnter);
item.addEventListener('mouseleave', handleMouseLeave);
});
});
onUnmounted(() => {
items.value.forEach((item) => {
item.removeEventListener('mouseenter', handleMouseEnter);
item.removeEventListener('mouseleave', handleMouseLeave);
});
});
</script>
此组件是具有多行和分页的表格中单元格的简化版本。
它并不总是为所有单元格记录 1 或 2 但如果我向事件侦听器添加超时,它总是正确记录 1 或 2:
setTimeout(() => {
items.value.forEach((item) => {
item.addEventListener('mouseenter', handleMouseEnter);
item.addEventListener('mouseleave', handleMouseLeave);
});
}, 5000);
有人知道为什么吗?
这是使用单元格的表格:
<Table>
<TableHeader
slot="table-header"
:columns="tableColumns"
/>
<TableBody
slot="table-body"
>
<TableRow
v-for="(entity, index1) in dataSource"
:key="currentItemOffset + index1"
:row="entity"
rowid="index1"
>
<TableCell
v-for="(item, index2) in entity"
:key="currentItemOffset + index2"
>
<ComponentWithIssue
:lines="item"
></ComponentWithIssue>
</TableCell>
</TableRow>
</TableBody>
</Table>
OP 通过使用以下事件解决了他的问题:
@mouseleave
@mouseenter
nextTick
,但它更像是一种 hack,而不是更好、更常见的做事方式。偶尔应与某些需要额外时间初始化的 3rd 方软件包一起使用。尽管如此,从用户用户体验的角度来看,它比使用 setTimeout
更好。