V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yesterdaysun
V2EX  ›  Vue.js

Vue3 编写的最佳实践是怎样的?

  •  
  •   yesterdaysun · 6 小时 46 分钟前 · 2184 次点击

    最近刚用上 Vue3, 我在写 Vue3 的时候总感觉代码非常的散, 稍微复杂的页面里, 就是一堆的 const ref, computed, 更不用说一堆的 xxxLoading, xxxVisible, showXXX, hideXXX, 感觉写 Vue2 的时候也没这么乱过, 如果说要提取所谓 Composiable 组件, 感觉又是一堆的 useXXX, 导出一堆的 xxx,xxx 好像也没好到哪里去, 是我写的姿势不对吗? 这方面的最佳实践到底是什么, 有没有哪个开源项目让我参考参考?

    29 条回复    2025-07-08 18:13:20 +08:00
    lepig
        1
    lepig  
       6 小时 43 分钟前
    vue3 相比 vue2 有什么优势的地方呢。
    我一个后端 ,想直接学 vue2 不知现在是否是正确的选择。 就是看了 vue2 文档感觉相对简单好入门一点
    lilu0826
        2
    lilu0826  
       6 小时 40 分钟前
    写习惯了就好,哈哈。 可以去看下 ElementPlus 组件库源码。
    shintendo
        3
    shintendo  
       6 小时 39 分钟前
    @lepig Vue3 + Options API
    jeodeng
        4
    jeodeng  
       6 小时 34 分钟前
    你写 vue3 用的组合式 API 写法吧?
    对于大型复杂项目来说,我觉得组合式 API 写法比较考验编写的个人能力,编写出可读性高的代码,不然很容易就乱了...
    但由于团队的人员不同,而且水平不一,我推荐大型多人协作的项目用选项式 API 写法,相对来说可读性高点,便于团队协作维护。
    如果是简单的小项目,组合式 API 写法确实快一些,而且方便。
    xuxiake
        5
    xuxiake  
       6 小时 32 分钟前
    彻底拥抱 Composition API
    yozoh1163
        6
    yozoh1163  
       6 小时 31 分钟前
    yesterdaysun
        7
    yesterdaysun  
    OP
       6 小时 26 分钟前
    我也想彻底拥抱 Composition API, 奈何实力不够啊, 一开始用 Cursor AI 帮我提取复用, 结果也是整出来一坨看着就毫无美感的代码, 想想还是得找大佬的例子学习学习
    Immortal
        8
    Immortal  
       6 小时 10 分钟前
    Vue 的正确姿势是 tsx
    visper
        9
    visper  
       6 小时 7 分钟前
    composition api 唯一的好处就是灵活吧。试下以这样的目标写代码:我这一块功能的代码都放在这里,如果不要这个功能直接把正块代码删除就行。不会影响其他功能。
    dfkjgklfdjg
        10
    dfkjgklfdjg  
       6 小时 3 分钟前   ❤️ 1
    是的,会有点乱。特别是在大组件的情况下。

    其实原本的 options api 也会有这样的问题,只不过在外层用 data ,computed ,methods 之类的包了下可以折叠起来,所以在折叠的情况下,看起来会更 "整洁" 一些。

    -----

    日常实际开发中逻辑复用的需求下会出现使用 mixins 和 extends 来混合代码的情况。
    composition api 的出现就是想要避免原本的隐式缺陷。👉 [#为什么要有组合式 API ? - 组合式 API 常见问答 | Vue.js]( https://cn.vuejs.org/guide/extras/composition-api-faq.html#why-composition-api)

    👇 所谓的整洁度其实也就是下面这样图这样,把相关联的业务逻辑放到一起来维护


    那么其实就是靠人的自觉来把相关的逻辑放到一起,如果没有开发规范或者一些约定,胡乱 Coding 就会出现混乱的感觉。
    👉 [#约定和最佳实践 - 组合式函数 | Vue.js]( https://cn.vuejs.org/guide/reusability/composables#conventions-and-best-practices)

    但其实可以把一些复杂逻辑的业务整理抽象成单独组合式函数,放到单独的 js, ts 文件中,在在业务组件中 import 进来使用。
    比如说:
    ```js
    <script setup>
    import { useFeatureA } from './featureA.js'
    import { useFeatureB } from './featureB.js'
    import { useFeatureC } from './featureC.js'

    const { foo, bar } = useFeatureA()
    const { baz } = useFeatureB(foo)
    const { qux } = useFeatureC(baz)
    </script>
    ```

    我一般会推荐组员把 SFC 的代码行控制在 400~600 行以内(包含了模板),太过于复杂的就会建议他们按照 **容器组件** 和 **展示组件** 的思想拆分。
    👉 [关于 React 的 Container&Presentational Component 模型结构分析 - Clark's Blog - SegmentFault 思否]( https://segmentfault.com/a/1190000007875199)
    momowei
        11
    momowei  
       6 小时 0 分钟前
    vue3 我用的挺爽的,比 react 我觉得更自然,除了 slot 这个天生的有点不方便没办法
    RogerL
        12
    RogerL  
       5 小时 54 分钟前   ❤️ 2
    我个人喜欢用 @tanstack/vue-query
    代码基本是这个风格:

    const { data, isLoading, refetch, edit } = useCurrentUser()
    const { data: options } = useUserOptions()

    基本上业务处理逻辑能扔的全扔到 hooks 里面

    api 各种接口全都用 openapi-typescript 去生成类型声明,用 useQuery 去封装

    常用库:
    es-toolkit
    @vueuse/core

    常用 vite 插件:
    unplugin-auto-import
    unplugin-vue-components
    unplugin-vue-router
    gefangshuai
        13
    gefangshuai  
       5 小时 46 分钟前
    乱不乱看个人,更容易封装了是真的
    9A0DIP9kgH1O4wjR
        14
    9A0DIP9kgH1O4wjR  
       5 小时 41 分钟前
    感觉还是 vue2 用着爽一点。。。
    shintendo
        15
    shintendo  
       5 小时 39 分钟前
    @visper 但实际上“一块功能”的代码往往也包含模版和样式,依然是分散的
    shintendo
        16
    shintendo  
       5 小时 35 分钟前   ❤️ 1
    这张图在所有组合式 API 的布道里都会出现,但我在实际中几乎没见过这种 case ,一个组件复杂到需要这样拆分逻辑,却又不能拆分子组件

    bojackhorseman
        17
    bojackhorseman  
       5 小时 24 分钟前
    其实 vue3 开启 setup 后方便很多,vue2 的 option 写法从别处 import 一个函数还要挂载到 data 里才能在 template 里用,如果后来这个函数不用了,清理冗余代码也是一件头疼的事。
    TimG
        18
    TimG  
       5 小时 21 分钟前 via Android
    我也是刚刚从 Vue2 切换到 Vue3 ,目前也是一头雾水。我想因为 Vue2 时代按照选项式已经写习惯了,即使换成 3 ,默认排序还是会不自觉按照类型去划分,而不是功能。到这一步,十分想要一个 C#的#region 块功能做代码块的功能注释,IDE 帮忙折叠代码块,这样会更好一些。
    话说回来,控件的逻辑多了,即使 js 内部紧密,距离 div 还是十万八千里,个人感觉这种单个“重控件”不是一种很好的实践,不如尝试解耦,就像 16#说的那样。
    dfkjgklfdjg
        19
    dfkjgklfdjg  
       5 小时 11 分钟前
    @shintendo #16 , 大部分人已经在日常开发中。已经按照自己的整洁偏好去整理了代码或者拆分了组件,所以没有什么感知。

    如果你点开 Vue 关于这个图片介绍部分的仓库链接就能看到了。
    👉 选项式 [vue-cli/packages/@vue/cli-ui/src/components/folder/FolderExplorer.vue at a09407dd5b9f18ace7501ddb603b95e31d6d93c0 · vuejs/vue-cli]( https://github.com/vuejs/vue-cli/blob/a09407dd5b9f18ace7501ddb603b95e31d6d93c0/packages/@vue/cli-ui/src/components/folder/FolderExplorer.vue#L198-L404)
    👉 组合式 [docs-zh-cn/assets/FileExplorer.vue at main · vuejs-translations/docs-zh-cn]( https://github.com/vuejs-translations/docs-zh-cn/blob/main/assets/FileExplorer.vue)

    其实和我们日常开发的代码结构没有什么差别。代码量其实也没有很大。
    我个人没有什么感觉,但是 Options API 需要在 data ,computed ,methods 来回反复横跳已经被社区诟病很久了。
    yesterdaysun
        20
    yesterdaysun  
    OP
       4 小时 56 分钟前
    @dfkjgklfdjg @shintendo 我对组合式这种集中业务逻辑的设计没有任何意见, 对于明显属于复用的代码, 可以分离成一个 Composable, 没有什么心智负担. 但是对于普通的业务组件, 就是一堆面条代码, 重要的不是复用, 而是切分组织不同功能点, 但是我对它的拆分管理的方法有疑问, 如果像图上这样, 一堆一堆的放在一起, 但是实际代码里面可没有这些颜色区分代码, 实际上就是一坨, 写多了自然就乱了. 我很想拆成不同文件, 但是就像前面说的, 之前尝试过有点失败, 分离成 useComposable 之后, 主页面就是一堆的{xxx,xxx,......}=userXXX 的代码, 括号里面可能一下子就是 8/9 个需要导出的参数, 看着就很累, 好像也不优雅.

    所以在拆分业务逻辑或者拆分子组件这一块, 到底应该怎么做比较好? 或者说你们真的很喜欢那种 useXXX, 然后导出 8/9 个参数的写法?
    dfkjgklfdjg
        21
    dfkjgklfdjg  
       4 小时 42 分钟前
    @dfkjgklfdjg #19 ,其实 composition api 的优势并不是在于上面逻辑关注点导致的**整洁度**上面。而是在把逻辑关注点相关的代码被归为了一块完整的业务逻辑代码,可以很容易地将这一组代码抽象到外部 JS 文件中,来实现逻辑复用和拆分。以及函数组织代码所提供的更好的类型推导。
    m319
        22
    m319  
       4 小时 34 分钟前
    我的感觉是即使不考虑复用,只要内容稍多且能拆分就要尽量拆组件,控制单组件大小,组件稍稍一大,代码想不乱都难,只要组件小,不管怎么写始终都是比较可控的,无论是 vue2 vue3 还是 react 或者纯 js 都是,唯一的问题是目录结构就比较多了
    visper
        23
    visper  
       4 小时 31 分钟前
    @shintendo 是的,最后最矛盾的就在这里,模板还是在外面了。所以也只是相对灵活。这种灵活程度还是不如 react.
    dfkjgklfdjg
        24
    dfkjgklfdjg  
       4 小时 10 分钟前
    @yesterdaysun #20 ,面条代码之间可以用空行或者注释行来区分。但是如果是很复杂了的情况, 可以继续拆组件(比如说我在 #10 中提到的容器、展示组件的思想),或者单纯只是把业务逻辑提取出来,然后通过函数返回值的形式来调用就可以了,并不一定要改成 useXXX 这样的形式。
    就是简单的函数返回:
    ```js
    async fcuntion fnA (X) {
    const valueB = fnB(XX)
    const fetchData = await fetchXXX()
    }

    function fnB(XXX) {
    ....
    return XXX
    }
    ```

    按照指责单一、关注点分离的思想去拆就可以了。至于是要在一个文件里面,还是拆分成多个文件就是看你自己的喜好。


    -----



    一些需要改造成 useXXX 的,常用的其实基本上都可以在 [VueUse]( https://vueuse.org/) 这个库里面找到。
    一些业务逻辑相关的,比如说 CURD 的管理页面就会抽象一个 useTable() 的 hooks 来使用。但是返回出来的变量也不一定都要使用,具体用到哪些就解构出来哪些就好了。如果按照你说的需要同时解出来 8 、9 个变量了。是不是应该考虑一下逻辑再拆分。

    不确定是否是最优解的场景,我的想法是找比较大的开源项目是怎么设计的,比如说我提到的 useTable ,社区的解决方案中就是再组装之后返回的,把相关的一些属性用一个属性包起来

    ```js
    export const useTable = (config: UseTableConfig) => {
    ....
    return {
    tableRegister: register,
    tableMethods: methods,
    tableState: {
    currentPage,
    pageSize,
    total,
    dataList,
    loading
    }
    }
    }
    ```
    [vue-element-plus-admin/src/hooks/web/useTable.ts at v2.10.0 · kailong321200875/vue-element-plus-admin]( https://github.com/kailong321200875/vue-element-plus-admin/blob/v2.10.0/src/hooks/web/useTable.ts#L184)
    UnluckyNinja
        25
    UnluckyNinja  
       3 小时 52 分钟前
    优点是比较出来的,vue3 优点在于更灵活,具体怎么做取决于开发者,vue2 时代 options API 很多地方是强耦合的,响应系统严重依赖于组件实例,this here this there ,vue3 我都几乎没见过 this 了

    迷茫时可以看看 VueUse ,Composable 的标杆

    #20
    > 或者说你们真的很喜欢那种 useXXX, 然后导出 8/9 个参数的写法?
    先不说有没有必要都放在同一个 composable 里,觉得返回值用解构式声明太多你可以不写解构声明,就用 reactive 包起来,例如`const mouse = reactive(useMouse())`,也是官方推荐的写法
    connection
        26
    connection  
       2 小时 35 分钟前
    你这种问题是 composition api 的书写模式的问题吧,跟 vue 版本倒是关系不大,毕竟 vue3 也可以使用类组件书写
    yesterdaysun
        27
    yesterdaysun  
    OP
       2 小时 21 分钟前
    看了上面几位大佬的讲解稍微有点感觉了, 不过回到最开始的主题, 有没有那种可以学习的开源库? 最好是那种业务逻辑面条代码一堆的, 学习一下别人是怎么处理这种代码耦合分离的问题的, 上面列出的几个库主要是组件库之类的
    dfkjgklfdjg
        28
    dfkjgklfdjg  
       2 小时 14 分钟前
    @yesterdaysun #27 ,我贴的是 Admin 框架,并不是 UI 库。里面有一些基础的通用页面,比如说用户管理、角色管理、菜单管理这种的,对于管理后台来说已经足够参考了。
    如果要复杂的具体业务逻辑那么多半不会开源出来,如果是非管理后台的需求,可以直接在 Github 中用关键词 + Vue 的组合去检索,按照 star 数量来排序慢慢找就好了。
    txzh007
        29
    txzh007  
       2 小时 7 分钟前
    vue3 写到最后肯定是 tsx 呀.
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2966 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:20 · PVG 20:20 · LAX 05:20 · JFK 08:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.