问题描述
我对Vue插槽并不十分满意,所以也许我错误地使用了它们。我有2个单一文件组件,它们通过以下方式定义:
HelloWorld.vue:
<template>
<div>
<div
v-for="item in items"
:key="item"
@mouSEOver="highlighted = item"
:class="{ highlighted: highlighted === item }"
>
{{ item }}
<Info>
<img
src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png"
/>
</Info>
</div>
</div>
</template>
<script>
import Info from "./Info.vue";
export default {
name: "HelloWorld",components: {
Info,},data: () => ({
highlighted: null,items: [1,2,3],}),};
</script>
<style scoped>
.highlighted {
background: grey;
}
</style>
Info.vue:
<template>
<div><slot /></div>
</template>
<script>
export default {
name: "Info",beforeUpdate() {
console.log("beforeUpdate Info.vue");
},};
</script>
我不了解的是:触发mouSEOver
SFC中的HelloWorld
事件时,beforeUpdate
的{{1}}方法每次被调用3次(次数是我列表中的所有项目)。如何调用此方法(由于没有更改传递到Info.vue
组件的数据),如何防止这种可能代价高昂的重新渲染?有趣的是,如果我删除了Info
中的class
属性来切换行高亮,则不会发生重新渲染。
完整代码在这里:https://codesandbox.io/s/tender-swanson-57oev
解决方法
之所以会这样,是因为每次发生鼠标悬停事件时,都必须为每个元素评估highlighted
类。
之所以发生这种情况,是因为highlighted
道具每次鼠标悬停都会发生变化,这会重新触发Vue以确定将highlighted
css类附加到哪个元素。