Vue渲染对比实验

123#mi4itikif983pk0codi

验证:当父组件在每次渲染时都传递匿名函数、匿名数组、匿名对象时,子组件会如何重新渲染,以及与缓存引用的做法相比有何差异。同时提供 SFC 与 TSX 两种实现对照,便于在不同语法下验证结论。

匿名 props 触发子组件渲染的对比结果

本文记录一次在 Vue 3 环境中针对“父组件传递匿名 props 是否导致子组件重新渲染”的实测结论,分别覆盖模板 (SFC) 与 TSX 写法。

实验现象概览

场景 匿名函数 匿名数组 匿名对象
Vue SFC 模板语法 触发 未触发 未触发
Vue TSX 触发 触发 触发

触发判断方式:子组件内部维护渲染计数与 props 引用变更计数,每次父组件更新后查看计数变化。

关键结论

1. SFC 模板语法

  • 模板中的字面量数组、字面量对象会被 Vue 编译阶段提升为常量引用,因此并不会在每次渲染时创建新引用。
  • 匿名函数会在每轮渲染时重新创建,导致子组件收到新函数引用而更新。
vue 复制代码
<template>
  <ChildProbe
    label="匿名 props"
    :fn="() => counter"
    :items="['a', 'b', 'c']"        <!-- 字面量数组被静态提升 -->
    :config="{ role: 'inline' }"    <!-- 字面量对象被静态提升 -->
  />

  <ChildProbe
    label="缓存 props"
    :fn="stableFn"
    :items="stableItems"
    :config="stableConfig"
  />
</template>

<script setup lang="ts">
const counter = ref(0)
const stableFn = () => counter.value
const stableItems = ['a', 'b', 'c']
const stableConfig = { role: 'stable' }
</script>

2. TSX 写法

  • TSX 中的字面量不会自动被静态提升,每次渲染都会重新生成函数、数组和对象的新引用。
  • 因此,匿名传参的三种类型都会触发子组件的 props 改变与重新渲染。
  • 通过在 setup 中提前声明并使用同一引用,可以消除多余渲染。
tsx 复制代码
export default defineComponent({
  setup() {
    const counter = ref(0)

    const stableFn = () => counter.value
    const stableItems = ['a', 'b', 'c']
    const stableConfig = { role: 'stable' }

    return () => (
      <>
        <TsxChildProbe
          label="匿名 props"
          fn={() => counter.value}
          items={['a', 'b', 'c']}
          config={{ role: 'inline' }}
        />

        <TsxChildProbe
          label="缓存 props"
          fn={stableFn}
          items={stableItems}
          config={stableConfig}
        />
      </>
    )
  },
})

3. 子组件如何统计

ts 复制代码
export function useRenderProbe(props) {
  const renderCount = ref(1)
  const referenceChanges = reactive({ fn: 0, items: 0, config: 0 })

  onUpdated(() => {
    renderCount.value += 1
  })

  watch(
    () => props.fn,
    (next, prev) => {
      if (next !== prev) referenceChanges.fn += 1
    }
  )

  // items、config 同理统计
}

建议

  • SFC 模板:仅需关注匿名函数,数组/对象字面量保持不变时可视为稳定引用。
  • TSX:若要避免额外渲染,应在 setup 中提前声明所有需要传入的函数、数组与对象,保证引用稳定。

参与本文讨论

请先登录 GitHub 后留言

0/500

本文留言

0

这篇文章还没有留言,来写第一条吧。

1 / 1