首页 > 解决方案 > 带有插槽的单个文件组件在父事件上意外重新渲染

问题描述

我对 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>

信息.vue:

<template>
  <div><slot /></div>
</template>

<script>
export default {
  name: "Info",
  beforeUpdate() {
    console.log("beforeUpdate Info.vue");
  },
};
</script>

我不明白的是:当触发SFC中的mouseover事件时,每次调用方法3次(与我列表中的项目一样多次)。这个方法是怎么被调用的(因为传递给组件的数据没有改变),我怎样才能防止这种潜在的代价高昂的重新渲染?有趣的是,如果我删除切换行高亮的属性,则不会发生重新渲染。HelloWorldbeforeUpdateInfo.vueInfoclassHelloWorld

完整代码在这里:https ://codesandbox.io/s/tender-swanson-57oev

标签: vue.jsvue-sfc

解决方案


发生这种情况是因为highlighted每次鼠标悬停事件发生时都必须为每个元素评估类。

发生这种情况是因为highlighted每次鼠标悬停时 prop 都会发生变化,这会重新触发 Vue 来确定要将highlightedcss 类附加到哪个元素。


推荐阅读