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

Vue 所有请求都应该放在 Vuex 里面吗?

  •  
  •   sxox · 2021-08-25 10:30:22 +08:00 · 8927 次点击
    这是一个创建于 937 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在定一些代码开发规范,有一个前端同学坚持要把所有请求按模块都放到 Vuex 里面?请问合理吗?
    90 条回复    2021-08-27 15:17:27 +08:00
    duan602728596
        1
    duan602728596  
       2021-08-25 10:32:52 +08:00
    不合理
    murmur
        2
    murmur  
       2021-08-25 10:34:01 +08:00
    放哪里都一样,只要维护方便就行
    musi
        3
    musi  
       2021-08-25 10:36:27 +08:00   ❤️ 3
    vuex 不是用来管理状态的么,难不成你们所有的请求都是状态?
    请求分模块能理解,全放到 vuex 里就不能理解了
    Twinkle
        4
    Twinkle  
       2021-08-25 10:38:19 +08:00   ❤️ 1
    大部分放 vuex 里面感觉没啥问题,还要看你们的页面数据是不是都从 vuex 里拿。单独提出一个 service 或者 api 的文件夹放下面也可以,都是便于维护的方式。
    timethinker
        5
    timethinker  
       2021-08-25 10:39:01 +08:00
    就是把数据源进行封装,有一定的好处,方便测试,就看这样做值还是不值,如果变化非常频繁就比较费事。
    SxqSachin
        6
    SxqSachin  
       2021-08-25 10:39:31 +08:00
    我们公司是把所有接口放到 api 文件夹中,再按不同功能模块继续细分文件夹。把所有请求放到 vuex 里是头一回听说
    murmur
        7
    murmur  
       2021-08-25 10:40:17 +08:00
    @musi vuex 两层封装简单理解点就是一层修改 state,一层可以是异步操作,修改一堆 state,当然也可以无聊封装直接调 commit
    从这个角度来看,远程请求是 promise,会修改一些 state,这个封装是没问题的
    iikebug
        8
    iikebug  
       2021-08-25 10:40:34 +08:00
    头一回听说还能这么用的
    ccyu220
        9
    ccyu220  
       2021-08-25 10:42:27 +08:00
    我个人认为只有涉及到基础信息或者全局公共的请求才放到 vuex 里面。

    比如:session 、login 、logout 以及页面上报、记录信息等。

    适时而定,一条路走死那叫极端。
    murmur
        10
    murmur  
       2021-08-25 10:44:05 +08:00
    @SxqSachin 这当然可以,但是换个角度想,你 api 里就写一个 axios({url: xxxx, params: xxxx}),和把这玩意直接塞 action 里,差别不大,为了三五行代码封装一个函数,说多余也多余
    Vegetable
        11
    Vegetable  
       2021-08-25 10:46:21 +08:00
    统一管理是对的,但是 vuex 显然不是最好的选择。
    keepeye
        12
    keepeye  
       2021-08-25 10:47:23 +08:00   ❤️ 4
    vuex 是管理全局状态的,反对将所有状态一股脑塞进去,更不用说将所有接口都塞进去了
    learnshare
        13
    learnshare  
       2021-08-25 10:49:07 +08:00
    见过这么做的,能运行
    但完全不可以,绝对不可以

    状态管理是用来存储、修改、共享和分发数据的,不应该包含任何副作用、异步过程和其他多余操作

    目前见过的一些状态管理使用状况,基本都是乱用,什么都放到状态管理中
    实际上应该谨慎使用状态管理,尽量少用或不用,真需要状态管理的数据和场景并不多
    qiaobeier
        14
    qiaobeier  
       2021-08-25 10:51:46 +08:00
    小项目随意,稍大点项目不推荐。
    Shook
        15
    Shook  
       2021-08-25 10:51:49 +08:00
    不应该。而且我本身比较讨厌 Vuex,所以 Vue3 以后,我认为 Vuex 都可以不用了。
    murmur
        16
    murmur  
       2021-08-25 10:52:04 +08:00
    @learnshare "不应该包含任何副作用、异步过程和其他多余操作"

    action 本身就可以返回异步,为啥不能包含异步过程

    我举个例子,https://github.com/PanJiaChen/vue-element-admin/blob/master/src/store/modules/user.js

    action 里的 login,login({ username: username.trim(), password: password }),把这行直接改成
    axios({url: "login.xxx", params:{xxxx}})没任何问题,一个函数多了 3 行而已,考虑到拆分后 module 也不大,不会对代码整洁度和管理造成多少影响
    Kusoku
        17
    Kusoku  
       2021-08-25 10:52:48 +08:00
    请求数据不是跟状态强关联的,放在 vuex 里属实有点欠妥,两个各自独立的东西只是在部分场景有耦合,强行放在一起有什么收益呢?如果涉及到状态管理方案的改造变更或者压根就不需要状态管理呢?
    sxox
        18
    sxox  
    OP
       2021-08-25 10:54:04 +08:00
    @Kusoku 美其名曰是为了 api 的复用,我实在是理解不了
    sxox
        19
    sxox  
    OP
       2021-08-25 10:54:21 +08:00
    @duan602728596
    @murmur

    你们是怎么做的
    murmur
        20
    murmur  
       2021-08-25 10:55:00 +08:00
    @sxox 我们的项目小,api 这层封装都没有,action 也不用,就只用 state 和 commit
    yamedie
        21
    yamedie  
       2021-08-25 10:56:02 +08:00
    我现在就是这样用的, actions 里面基本全是各种 api 调用, 有些回参需要缓存的, 在 action 里调用 commit 把字典接口的回参缓存到 state, 下次调 action 时发现 getters 里有这个字典的缓存, 就直接将它 return 出来, 很顺滑而且自然. (当然如果是列表之类一次性的请求, 直接将 promise 返出去就可以了
    KouShuiYu
        22
    KouShuiYu  
       2021-08-25 11:02:14 +08:00
    learnshare
        23
    learnshare  
       2021-08-25 11:04:36 +08:00
    @murmur 并不是能做,我们就要做。

    项目简单的话,放一起不觉得乱。
    但项目规模大,合作人员多的话,还是要追求模块分层清晰,代码逻辑简单。

    我前边说 vue-element-admin:
    >类似的项目通常缺乏最佳实践,配套工具和代码风格不太好,导致项目质量不高。
    还被骂乱配、乱踩来着,神都吹上了
    darknoll
        24
    darknoll  
       2021-08-25 11:05:03 +08:00
    你是不是看了 vue-element-admin, 他放归他放,你自己随便
    learnshare
        25
    learnshare  
       2021-08-25 11:05:34 +08:00
    @learnshare 乱配 -> 乱喷
    murmur
        26
    murmur  
       2021-08-25 11:06:43 +08:00
    @learnshare 你觉得为了所谓的清晰把 2 行代码封装成 1 个函数属于最佳实践么

    现在基本上都是拦截器统一处理异常,也就是说 api 封装是没有 catch 部分的

    那这个 2 变 1 的封装有何意义
    yamedie
        27
    yamedie  
       2021-08-25 11:07:35 +08:00
    @murmur 我完全同意#16 楼的观点, 这样做能减少各种弯弯绕(比如甚至单独定义一个 MutationTypes.js)带来的心智负担. 肯定有人会说大型项目不能这么做, 我还真没有经手过什么大型项目... Vuex 按模块拆分并开启命名空间, 每个模块负责一个"实体"(例如订单 /联系人 /对话 /合同都是实体), 每个 action 对应一个后端接口, 每个 action 是名字尽量语义化 /自注释, vue 组件里用 mapActions 引入... 至少给我带来的开发体验是很不错的
    cs419
        28
    cs419  
       2021-08-25 11:07:41 +08:00
    工业化讲究: 够用就好
    结合实际情况再加两条: 领导要求的 避免负面作用

    够用: 即保障基本需求
    领导要求: 领导觉着加了某个东西风水好,虽然可能没啥用,但领导不高兴肯定影响工作
    负面: 某个东西不能提供生产 反而导致老出问题 肯定也不行
    sjzjams
        29
    sjzjams  
       2021-08-25 11:08:44 +08:00
    那你所有的状态管理后面需要维护的就很多
    learnshare
        30
    learnshare  
       2021-08-25 11:21:18 +08:00
    @murmur 不是几行代码的问题,是为了保证模块专注在一件事上

    项目越复杂,参与人员越多,就更需要
    >模块分层清晰,代码逻辑简单。
    xu2060
        31
    xu2060  
       2021-08-25 11:23:52 +08:00
    我们这就是这样做的把所有的请求都放在 vuex actions 里面 然后数据都存在 state 里面,虽然整齐,但是这么用肯定不对
    PerFectTime
        32
    PerFectTime  
       2021-08-25 11:23:57 +08:00
    element-admin 似乎就是把 api 放在状态里面的
    thtznet
        33
    thtznet  
       2021-08-25 11:25:39 +08:00
    所以,讨论到最后发现都是设计模式问题,那么干嘛用 VUE ? NG 就很香了对么?
    violetlai
        34
    violetlai  
       2021-08-25 11:28:10 +08:00
    感觉不太合适吧 毕竟 vuex 就不是处理请求的东西 偶尔需要用共享数据才用它 请求还是同一拦截处理比较好

    其次 vuex 是用的真的很难受
    wht0522
        35
    wht0522  
       2021-08-25 12:03:58 +08:00 via Android
    第一次见到这种方式属实惊呆了 所有接口都放到 vuex 很不方便 element-admin 只是退出 登录 获取用户信息 这几个接口放在这里边
    SSSensational
        36
    SSSensational  
       2021-08-25 12:16:01 +08:00
    为什么不试试 swrv,以及 vue 下的 umi-hooks/useRequset 。这些只是取数的场景不需要用 store 的。
    SZP1206
        37
    SZP1206  
       2021-08-25 12:20:28 +08:00 via Android
    不合理
    Geo200
        38
    Geo200  
       2021-08-25 13:17:11 +08:00
    这明显是把 MVVM 当 MVC 来用了
    Lemeng
        39
    Lemeng  
       2021-08-25 13:18:47 +08:00
    一般都有规范要求,不然怎么方便怎么来呗
    cansiny0320
        40
    cansiny0320  
       2021-08-25 13:22:39 +08:00
    我觉得可以,全放在 action 里
    liyg04120414
        41
    liyg04120414  
       2021-08-25 13:34:10 +08:00
    不需要维护状态的请求没必要放到 vuex 里
    3wdddd
        42
    3wdddd  
       2021-08-25 13:59:49 +08:00
    副作用太大,不太好
    gloye
        43
    gloye  
       2021-08-25 15:04:20 +08:00
    我看过一个国外的示例项目倒是这么做的,意思同一个业务模块可以对接多个业务来源,例如同一页面需要 A 部门接口,B 部门接口,那么可以放到一个 module 里统一管理。
    voidWhyy
        44
    voidWhyy  
       2021-08-25 15:10:33 +08:00
    我认为只有 login 和 logout 相关的才需要放到 vuex 里
    strangeFish
        45
    strangeFish  
       2021-08-25 15:10:48 +08:00
    完全不推荐,api 应该统一管理是对的。
    如果你们后端使用 swagger,而且项目是不在意体积的,推荐使用 https://github.com/alibaba/pont,全自动生成请求和类型提示。
    另外 vuex 非常不推荐使用。
    fox2081
        46
    fox2081  
       2021-08-25 15:20:51 +08:00
    既然要定规范一定不是小项目了,建议请求实例、文档等相关内容放在一个 npm 私有仓库,用脚本实现后端触发自动构建更新版本,api 自动封装,其他项目直接 npm 安装使用,省去人工修改的烦恼。
    和 vuex 混在一起这种方法我也见过,但是实在想不出来这样做图啥,vuex 是为了存储一个全局状态,一般也就存储个项目配置和用户相关。
    项目随着时间推移,复杂度会逐渐上升,最好在一开始就降低耦合和依赖,尽量模块化,要不然早期一些糟糕的设计逐渐就变成了屎山,后面再想着维护的成本就是指数级别的。
    gzf6
        47
    gzf6  
       2021-08-25 16:14:33 +08:00 via Android
    我接手过一个就是全放在里面的,改得想死,直接重构了一个
    ChefIsAwesome
        48
    ChefIsAwesome  
       2021-08-25 16:14:42 +08:00
    我见过一堆人就拿这玩意当全局变量使。一个文件成百上千行。就这还觉得自己模块清晰。
    anguiao
        49
    anguiao  
       2021-08-25 16:20:28 +08:00
    闻所未闻
    toesbieya
        50
    toesbieya  
       2021-08-25 16:23:01 +08:00
    有一说一,我觉得 vuex 除了能配合 vue devtool 以外,真的垃圾,完全没有语法提示,不如自己用 Vue.observable 写
    murmur
        51
    murmur  
       2021-08-25 16:25:47 +08:00   ❤️ 1
    @toesbieya 来了来了,拉不出屎赖框架,以前 jquery 年代都做大项目,现在换 vue 做不了了,是框架垃圾还是人太水
    chouchoui
        52
    chouchoui  
       2021-08-25 16:27:59 +08:00
    @toesbieya 换 pinia 吧,解决一切烦恼
    murmur
        53
    murmur  
       2021-08-25 16:31:20 +08:00
    自由和规矩只能选一个,自己场景搞不清楚赖框架垃圾是什么臭毛病

    你这种自己封一个 dispatch(ACTION.SOME_ACTION, ACTION.SOME_ACTION_ARGS(arg1, arg2))...

    能不能提示?
    yor1g
        54
    yor1g  
       2021-08-25 16:42:01 +08:00
    涉及状态共享的变化放进去也没毛病 既然都上了 vuex 统一放进去也是应该吧
    zhangjiancheng
        55
    zhangjiancheng  
       2021-08-25 17:53:52 +08:00
    vuex 的语法提示不算差了 mapXXX 之类的都带好了 完全没语法提示简直是扯
    TomatoYuyuko
        56
    TomatoYuyuko  
       2021-08-25 17:58:19 +08:00
    放 vuex 既不合理又不方便,我 vue 项目加了 ts,axios 做一层总的过滤器,然后根据业务分别把 api 放到对应的 ts 文件里,需要调接口的时候直接 await api(params),还有参数提示,这不简单多了?
    Melting
        57
    Melting  
       2021-08-25 18:01:30 +08:00
    这样搞耦合性太大了,放在 api 文件夹下也很方便,而且项目切换前端语言的时候,api 下的文件可以直接用。vuex 可以适量的用,全部放进去我觉得没必要
    varzy
        58
    varzy  
       2021-08-25 18:26:14 +08:00 via iPhone
    反对。个人认为 vuex 里面的东西应该越少越好。
    suzic
        59
    suzic  
       2021-08-25 19:42:35 +08:00 via Android
    不合理,应该只放会频繁使用的请求,比如
    zhwithsweet
        60
    zhwithsweet  
       2021-08-25 20:10:45 +08:00
    vuex 替代产品 https://pinia.esm.dev/ 试试这个?
    不是所有的请求都放 vuex,无状态的请求,直接写到组件逻辑即可。
    zesenwu
        61
    zesenwu  
       2021-08-25 22:29:49 +08:00
    不合理,vuex 本身就是用来存放全局状态的,应该少用,甚至不用
    很多框架的东西,如果原项目已经可以满足,那就不要引入太多其他东西
    不要为了用而用
    Rocketer
        62
    Rocketer  
       2021-08-25 23:33:37 +08:00 via iPhone
    @thtznet #33 就我见过的前端口水战而言,归根结底都是见的太少,又懒得学新,每个人都抱着自己会的那点东西拼命说它好。

    包括那些所谓的主管。

    由于历史包袱以及公司合并等原因,我三大 spa 框架都在用,所以我算是真正体会过三者的区别的。凭心而言,ng 是最优雅的,其 service 的概念绝对碾压 redux 和 vuex,以至于我都想试试在 react 和 vue 项目里引入这个概念。只可惜我也懒,懒得修改屎山,所以迄今为止也就是想想。
    jinwyp
        63
    jinwyp  
       2021-08-26 02:14:19 +08:00
    95%的项目,都不需要用到 vuex, 除非你要做个在线 excel word 这种。 看了上面的回帖,vue2 还是很多问题,到现在也没有最佳实践。

    我觉得不用 vuex 就是最佳实践。用了以后,根本无法区分哪些数据放到 vuex 里面, 哪些不放,最后就是乱成一锅粥
    sjhhjx0122
        64
    sjhhjx0122  
       2021-08-26 08:33:27 +08:00
    上 ts 就不用 vuex,上了 ts,直接用 ref 自己实现一个简易的 vuex,vuex 这个东西真的好维护嘛,...map 这种一点提示都没有,分了子模块也恶心
    TimPeake
        65
    TimPeake  
       2021-08-26 09:02:41 +08:00
    说实话 我现在极力推荐三大框架的作者去掉状态管理的相关功能, 为啥 ?状态管理已经被滥用到了恶心的地步....接收那种项目心里很排斥
    TimPeake
        66
    TimPeake  
       2021-08-26 09:03:55 +08:00
    天天还有一大帮人在问状态管理器的状态为啥刷新没了这种问题
    daguaochengtang
        67
    daguaochengtang  
       2021-08-26 09:06:00 +08:00
    阿这。。。
    asiasky
        68
    asiasky  
       2021-08-26 09:36:16 +08:00
    不建议这样 vuex 是状态管理 我猜你想放进去只是想可以直接调用 不用反复写或者引用了 但是其实这个用 require.context 去读文件实现
    IanHo
        69
    IanHo  
       2021-08-26 09:38:15 +08:00
    绝对不能接受
    ColdBird
        70
    ColdBird  
       2021-08-26 09:46:10 +08:00
    接口层放在 api 文件,数据层根据是否需要共享决定放在 vue 文件里还是 vuex 里,大部分都在 vue,少部分共享数据放 vuex
    yamedie
        71
    yamedie  
       2021-08-26 10:21:21 +08:00
    @TimPeake #66 vuex 有 persistedState 这种持久化插件, 页面刷新了该保留的 state 都还在, 不想保留的键值也可以自己写 reducer 让它不持久化, 我用着挺开心的, 就想问你们这些极力推崇 ref 代替 vuex 的人是怎么解决"刷新页面状态丢失"这个问题的?
    strangeFish
        72
    strangeFish  
       2021-08-26 10:54:51 +08:00
    @yamedie 本质是把状态存在 sessionStorage 或者 localStorage,自己写对应逻辑不难。。。

    ```ts
    function usePersistState(key: string, initValue = {}) {
    const str = localStorage.getItem(key)

    const oldState = str && JSON.parse(str)
    const someState = ref(oldState || initValue)

    watch(() => someState.value, val => {
    localStorage.setItem(key, JSON.stringify(val))
    }, {
    deep: true
    })
    return someState
    }
    ```
    yamedie
        73
    yamedie  
       2021-08-26 11:20:37 +08:00
    @strangeFish 这段代码能让散落在各处的 useFunction.js 都实现状态持久化吗?
    TimPeake
        74
    TimPeake  
       2021-08-26 11:24:46 +08:00
    @yamedie “”如何解决刷新页面状态丢失“” 就不应该有这种问题。我知道有持久化插件,但是这种持久化插件显然不够优雅。持久化注定是跟状态管理没一毛钱关系的 ,既然都持久化了 本地存储它不香。如果某个状态需要持久化,只能说明这个状态不适合放在状态里
    yamedie
        75
    yamedie  
       2021-08-26 11:24:50 +08:00
    而且代码里只看到了 watch 到改变->存 localStorage 的过程, "页面刷新后从 storage 中读取并恢复"的伪代码没有看到, 另外怎么复用到所有的 use 里?
    yamedie
        76
    yamedie  
       2021-08-26 11:33:59 +08:00
    @TimPeake 不太明白, 你的意思是往 localstorage 里存几十个键值对更优雅吗? 比如用户所属的部门和组的信息, 是不是一种状态? 我想存在 vuex 中全局共享, 刷新页面也不丢失, 只在希望主动更新时才调接口获取并更新, 否则一律使用缓存中的部门 /组别信息, 这是一种伪需求吗?
    TimPeake
        77
    TimPeake  
       2021-08-26 11:42:32 +08:00
    @yamedie 没记错的话,你说的 persistedState 实现原理也是通过本地存储辅助实现的吧,既然这样,有什么区别呢 ?如果你说 几十个键值对不优雅的话,那只是写法的问题罢了, 封装一些实现或者用 web sql 等也可以啊
    yamedie
        78
    yamedie  
       2021-08-26 11:47:49 +08:00
    @TimPeake 我是在反驳你这句话: "持久化注定是跟状态管理没一毛钱关系的 ,既然都持久化了 本地存储它不香。"
    用户姓名 /头像 url/部门名 /组名等等, 这类不常变动的信息是不是属于状态的一种, 你可以选择单独存 localstorage 或者频繁调接口获取, 但好像无力反对别人存 vuex(并持久化)的做法吧, 在我看来 vuex 这个状态机主要就是用来维护这些状态的
    TimPeake
        79
    TimPeake  
       2021-08-26 11:56:34 +08:00
    @yamedie 你是不是忘记了状态管理的诞生初衷是为了解决跨组件数据沟通 你觉得跟“用户姓名 /头像 url/部门名 /组名”这个需求一致吗
    yamedie
        80
    yamedie  
       2021-08-26 12:00:38 +08:00
    @TimPeake 我举例的“用户姓名 /头像 url/部门名 /组名”这类信息本来就是需要跨组件共享的呀
    yamedie
        81
    yamedie  
       2021-08-26 12:08:26 +08:00
    我不知道 @murmur 有没有兴趣驳斥"vuex 状态管理就不应该存在 / 状态管理跟持久化没一毛钱关系 / ref 能完全取代 vuex"这类观点
    shakukansp
        82
    shakukansp  
       2021-08-26 13:04:26 +08:00
    全部存 vuex 里面……是没做过几百个页面每个页面的参数不一样的系统吗
    murmur
        83
    murmur  
       2021-08-26 14:05:10 +08:00
    @yamedie 有,你可以不用啊,vue 本身就是选词填空,你把空填到哪里能完成功能不就行了
    SSSensational
        84
    SSSensational  
       2021-08-26 14:15:11 +08:00
    @yamedie @TimPeake 别吵了。看看 swrv / vue-request
    brookepe
        85
    brookepe  
       2021-08-26 14:31:18 +08:00
    vuex 可能是因为 this 这种用起来方便
    qq1340691923
        86
    qq1340691923  
       2021-08-26 14:42:43 +08:00
    还真是前端娱乐圈
    yunye
        87
    yunye  
       2021-08-26 14:44:27 +08:00
    这也能吵起来吗
    xqk111
        88
    xqk111  
       2021-08-26 16:36:25 +08:00
    不应该,下一个问题
    Quarter
        89
    Quarter  
       2021-08-27 12:11:24 +08:00 via iPhone
    这个我一直都觉得很奇怪,请求为啥都要放在 vuex 里面呢,没啥优势啊,如果多个地方调用封装成模块就可以了,还是说所有的数据都要 vuex 缓存,我觉得也没有啥必要,很多数据都是执行时的数据,加一层这样的缓存毫无意义
    zoffy
        90
    zoffy  
       2021-08-27 15:17:27 +08:00
    可以理解为:为了方便控制内部状态,你写 Class 的时候不写 private 只写 public
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4840 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 10:03 · PVG 18:03 · LAX 03:03 · JFK 06:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.