Vue3 defineComponent vs defineOptions 区别?script setup 实战用法

37 阅读4分钟

同学们好,我是 Eugene(尤金),一个拥有多年中后台开发经验的前端工程师~

(Eugene 发音很简单,/juːˈdʒiːn/,大家怎么顺口怎么叫就好)

你是否也有过:明明学过很多技术,一到关键时候却讲不出来、甚至写不出来?

你是否也曾怀疑自己,是不是太笨了,明明感觉会,却总差一口气?

就算想沉下心从头梳理,可工作那么忙,回家还要陪伴家人。

一天只有24小时,时间永远不够用,常常感到力不从心。

技术行业,本就是逆水行舟,不进则退。

如果你也有同样的困扰,别慌。

从现在开始,跟着我一起心态归零,利用碎片时间,来一次彻彻底底的基础扫盲

这一次,我们一起慢慢来,扎扎实实变强。

不搞花里胡哨的理论堆砌,只分享看得懂、用得上的前端干货,

咱们一起稳步积累,真正摆脱“面向搜索引擎写代码”的尴尬。

一句话总结defineComponent 用来「完整声明一个组件」,多用于非 <script setup> 和组件库;defineOptions<script setup> 专用,用来补充 name、inheritAttrs 等选项,业务开发用它就够了。

Vue3 开发中,很多人在 defineComponentdefineOptions 之间纠结。本文讲清楚二者的区别、适用场景,以及你在 <script setup> 里该用哪个,并附完整代码示例,看完就能直接用。

一、defineComponent 是什么?作用和用法

defineComponent 是 Vue 提供的「组件声明函数」,用来完整定义一个组件,包括 name、props、emits、setup 等全部配置,同时提供 TypeScript 类型支持。

1.1 典型写法(非 <script setup>

<script>
  import { defineComponent } from 'vue'
  export default defineComponent({
    name: 'IndexPage',
    props: {
      msg: String,
      type: { type: String, default: 'primary' }
    },
    emits: ['change'],
    setup(props, { emit }) {
      const handleClick = () => emit('change', props.msg)
      return { handleClick }
    }
  })
</script>

1.2 适用场景

  • 传统写法(不用 <script setup>
  • 封装组件库、需要完整控制组件选项
  • TS 项目中对 props、emits 做类型约束

注意:在 <script setup> 里通常不需要再用 defineComponent,语法糖已经帮你完成组件声明。

二、defineOptions 是什么?作用和用法

defineOptions 是 Vue 3.2+ 为 <script setup> 提供的辅助函数,用来补充组件选项(name、inheritAttrs 等),而不必退回 export default {} 写法。

2.1 典型写法(仅用于 <script setup>

<script setup lang="ts">
  defineOptions({
    name: 'IndexPage',
    inheritAttrs: false,
  })

  const props = defineProps<{ msg: string }>()
  const emit = defineEmits<['change']>()
</script>

2.2 常用可配置选项

选项说明
name组件名,常用于 DevTools、递归、ESLint
inheritAttrs是否继承父组件非 props 属性
components局部组件注册
directives局部指令注册
emits声明组件事件(可配合 defineEmits)

三、defineComponent vs defineOptions 对比表

对比项defineComponentdefineOptions
核心作用完整声明一个 Vue 组件在 script setup 中补充组件选项
典型场景非 script setup、组件库封装、TS 类型script setup 业务组件
是否依赖 script setup否,语法糖中不推荐使用是,只能在 script setup 中使用
常用配置name、props、emits、setup、components 等name、inheritAttrs、components、directives 等

四、script setup 里该用 defineComponent 还是 defineOptions?

结论:用 defineOptions,不用 defineComponent

推荐组合:

  • propsdefineProps + withDefaults
  • emitsdefineEmits
  • name / inheritAttrs 等defineOptions
<script setup lang="ts">
  defineOptions({ name: 'IndexPage', inheritAttrs: false })
  const props = withDefaults(defineProps<{ msg?: string }>(), { msg: 'hello' })
  const emit = defineEmits<['change']>()
</script>

只有少数高级 TS 封装场景才可能在 <script setup> 里配合 defineComponent 使用,一般业务代码用不到。

五、常见问题 FAQ

Q1:defineComponent 和 defineOptions 有什么区别?

defineComponent 用来「完整定义一个组件」,适合非 <script setup> 和组件库;defineOptions 只用于 <script setup>,用来补充 name、inheritAttrs 等选项,不负责声明组件本身。

Q2:script setup 里还需要 defineComponent 吗?

一般不需要。<script setup> 会自动完成组件声明,用 defineOptions 配 name、inheritAttrs 即可。

Q3:如何给 Vue 组件设置 name?

<script setup> 中:defineOptions({ name: 'YourComponentName' })

Q4:defineOptions 可以配哪些选项?

常见有:nameinheritAttrscomponentsdirectivesemits 等,等同于 export default {} 里的选项。

Q5:defineComponent 主要用在什么场景?

<script setup> 写法、组件库封装、需要对 props/emits 做 TS 类型约束时使用。

六、速记口诀

script setup 用得多,defineOptions 配选项;nameinheritAttrs 它来管,propsdefinePropsemitsdefineEmits,业务开发就够了。


学习本就是一场持久战,不需要急着一口吃成胖子。哪怕今天你只记住了一点点,这都是实打实的进步。

后续我还会继续用这种大白话、讲实战方式,带大家扫盲更多前端基础。

关注我,不迷路,咱们把那些曾经模糊的知识点,一个个彻底搞清楚。

如果你觉得这篇内容对你有帮助,不妨点赞+收藏,下次写代码卡壳时,拿出来翻一翻,比搜引擎更靠谱。

我是 Eugene,你的电子学友,我们下一篇干货见~