I am not very confortable with Vue slots yet so maybe I'm using them wrongly. I have 2 Single File Components that are defined the following way :
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>
What I don't understand is : when the mouseover event in the HelloWorld SFC is triggered, the beforeUpdate method of Info.vue is called 3 times each time (as many times as there are items in my list). How come this method is called (since no data passed to the Info component is changed) and how can I prevent this potentially costly re-render? Interestingly, the re-render doesn't happen if I remove the class attribute in HelloWorld that toggles the line highlight.
The full code is here : https://codesandbox.io/s/tender-swanson-57oev
This is happening because
highlightedclass has to be evaluated for each element, every time mouseover event takes place.This happens because
highlightedprop changes every time mouseover takes place, which re-triggers Vue to figure out which element to attach thehighlightedcss class to.