写Vue项目时间长了以后,会发现一个很现实的问题:

组件到底应该拆多小?

拆得太少,一个页面几百甚至上千行。

拆得太多,一个简单页面打开就是十几个组件。

所以组件拆分并没有一个绝对标准,我更倾向于从"职责"来判断。

不要为了拆组件而拆组件

比如:

<template>
  <button class="button">
    {{ text }}
  </button>
</template>

如果这个按钮只在一个页面出现,而且没有复杂逻辑,那没必要为了组件化而单独创建一个文件。

反过来,如果项目里几十个地方都用同一个按钮,那它就值得抽成公共组件。

所以我一般会问三个问题:

  1. 会不会复用?
  2. 有没有独立逻辑?
  3. 有没有独立的业务职责?

满足其中一个或多个,就可以考虑拆。

UI组件和业务组件应该区分开

这是我比较推荐的一种方式。

比如:

components/
├── Button.vue
├── Modal.vue
├── Input.vue
└── Table.vue

这些属于通用UI组件。

而:

features/
├── UserList/
├── OrderList/
└── Dashboard/

属于业务功能。

这样做的好处是:

通用组件不需要知道业务。

比如Button不应该知道:

createUser()
deleteOrder()
submitForm()

它只需要负责:

<Button
  :loading="loading"
  @click="submit"
/>

Props负责输入

一个组件应该尽量通过Props接收外部数据。

比如:

interface Props {
  title: string
  loading?: boolean
}

const props = defineProps<Props>()

调用:

<UserCard
  title="用户信息"
  :loading="loading"
/>

这样组件的依赖关系就比较明确。

Emits负责输出

子组件不要直接修改父组件的状态。

比如:

const emit = defineEmits<{
  submit: []
}>()

点击时:

emit('submit')

父组件:

<UserForm @submit="handleSubmit" />

这种方式让数据流更清晰:

Parent
  ↓ Props
Child
  ↓ Emits
Parent

一个组件什么时候算太大?

我不会简单用"超过300行就必须拆"这种规则。

更有意义的判断方式是:

这个组件里面是不是存在多个完全不同的职责?

比如一个页面同时负责:

用户搜索
用户列表
分页
用户编辑
用户删除
权限判断
弹窗

这时候就应该考虑拆分。

可以变成:

UserPage.vue
├── UserSearch.vue
├── UserTable.vue
├── UserPagination.vue
└── UserEditDialog.vue

页面负责组合。

子组件负责具体功能。

复杂逻辑应该挪到composable里

如果一个组件里面出现大量:

watch()
computed()
async function()

而且这些逻辑和UI没有强绑定,那就可以考虑抽出来。

比如:

UserPage.vue
       ↓
useUsers()
       ↓
API

这样:

const {
  users,
  loading,
  loadUsers,
  deleteUser
} = useUsers()

页面主要负责UI。

业务逻辑交给composable管理。

我现在更倾向按功能组织

随着项目规模变大,我越来越不喜欢:

components/
views/
utils/
api/
hooks/

下面堆几百个文件。

对于大型项目,我更倾向:

features/
├── user/
│   ├── components/
│   ├── composables/
│   ├── api.ts
│   └── types.ts
│
├── order/
│   ├── components/
│   ├── composables/
│   ├── api.ts
│   └── types.ts

这样一个功能的相关代码都在相对集中的位置。

以后改用户模块,不需要在整个项目里到处翻。

组件设计没有唯一答案

Vue本身提供了很灵活的组件系统。

真正重要的不是:

"我的组件是不是足够小?"

而是:

"这个组件的职责是不是足够清晰?"

一个200行但职责单一的组件,可能比50行但职责混乱的组件更容易维护。

所以在实际开发中,我现在更看重职责边界、数据流和复用价值,而不是单纯追求组件数量。

这也是一个Vue项目从"能跑"逐渐走向"好维护"的过程中,很重要的一步。

最后修改:2026 年 09 月 02 日
如果觉得我的文章对你有用,请随意赞赏