You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3组合式API中组件扩展与重写的最优方案咨询

Vue组件复用+重写的最优简洁方案

最直接贴合你需求的实现方式是用Vue原生的extends组件继承,既能完整复用通用组件的模板和大部分逻辑,又能轻松重写指定的ref、函数,完全不需要额外复杂封装。

具体实现步骤

1. 通用组件(common.vue)保持原样即可

不需要做任何大改动,正常定义你的模板和逻辑:

<template>
  <div>
    <div>Title</div>
    <div>{{ refToOverride.value }}</div>
  </div> 
</template>
<script>
import { defineComponent, ref} from 'vue'; 
export default defineComponent({
  name: "common",
  setup() {
    const refToOverride= ref("object to override");

    function functionToOverride() {
      return "Override me!"
    }

    return {
      refToOverride,
      functionToOverride,
    };
  },
});
</script>

2. 编写继承组件(比如叫Specific.vue)

通过extends继承通用组件,在自己的setup里重写需要修改的内容就行——Vue会自动合并逻辑,重写的部分会覆盖父组件的对应内容:

<!-- 这里不需要手动写<common/>,直接复用父组件的模板 -->
<template></template>

<script>
import { defineComponent, ref } from 'vue'; 
import Common from './common.vue'

export default defineComponent({
  extends: Common, // 关键:继承通用组件
  setup() {
    // 重写ref
    const refToOverride = ref("I override a ref");

    // 重写函数
    function functionToOverride() {
      return "I override a function!"
    }

    // 如果还需要复用父组件的其他逻辑,可以调用父组件的setup获取
    // const parentLogic = Common.setup();
    // 比如用parentLogic里的其他方法

    return {
      refToOverride,
      functionToOverride
    };
  },
});
</script>

为啥你原来的写法行不通?

你直接修改导入的common组件对象的属性是错的:

  • common是组件的构造函数,不是实例,直接改会影响所有用到这个组件的地方,相当于全局污染
  • 每个组件实例的ref和函数都是独立的,构造函数上根本不存在refToOverride这类实例属性

备选方案:插槽+组合式函数(适合需要改模板的场景)

如果你的需求不止是重写逻辑,还需要替换部分模板内容,可以结合插槽和组合式函数:

  1. 先把通用逻辑抽成组合式函数:
// useCommonLogic.js
import { ref } from 'vue';
export function useCommonLogic() {
  const refToOverride = ref("object to override");
  function functionToOverride() {
    return "Override me!"
  }
  return { refToOverride, functionToOverride };
}
  1. 通用组件改用插槽+组合式函数:
<template>
  <div>
    <div>Title</div>
    <!-- 用插槽预留可替换的内容 -->
    <slot name="content">
      <div>{{ refToOverride.value }}</div>
    </slot>
  </div> 
</template>
<script>
import { defineComponent } from 'vue';
import { useCommonLogic } from './useCommonLogic';
export default defineComponent({
  name: "common",
  setup() {
    return useCommonLogic();
  },
});
</script>
  1. 业务组件使用时:
<template>
  <common>
    <template #content>
      <div>{{ refToOverride.value }}</div>
    </template>
  </common>
</template>
<script>
import { defineComponent, ref } from 'vue'; 
import Common from './common.vue'

export default defineComponent({
  components: { Common },
  setup() {
    const refToOverride = ref("I override a ref");
    function functionToOverride() {
      return "I override a function!"
    }
    return { refToOverride, functionToOverride };
  },
});
</script>

不过如果只是单纯重写逻辑和ref,extends方案明显更简洁直接。

内容的提问来源于stack exchange,提问作者JulienRobitaille

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:20:08