vue3 hooks 可以转为 esm 写法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chill777
V2EX    Vue.js

vue3 hooks 可以转为 esm 写法?

  •  
  •   chill777 2023-12-18 13:47:46 +08:00 3555 次点击
    这是一个创建于 664 天前的主题,其中的信息可能已经有所发展或是发生改变。

    pi5j5xH.png 之前的项目给别人写了,再拿过来的时候发现我的 hooks 被拆掉了。所以这种写法是可以的吗?

    对方居然还说感觉这样更合理。。。

    第 1 条附言    2023-12-18 21:24:16 +08:00
    其实我只是想吐槽一下工作遇到的奇葩而已。

    但是感觉一些人对 hooks 、闭包和模块化的基本概念都不了解。

    (后续:第二种写法的项目的确会有 bug )
    35 条回复    2023-12-20 13:27:38 +08:00
    horizon
        1
    horizon  
       2023-12-18 13:54:34 +08:00
    1. 什么叫 esm 写法?
    2. 第二种相当于创建了一个 chartDataObj 的响应式对象 单例

    看你们的需求。。
    在没有更多背景的前提下,你的更好,没看到拆分的好处。但是单例的问题很大。
    abelmakihara
        2
    abelmakihara  
       2023-12-18 13:58:39 +08:00
    这个图里好像看不出来什么
    因为他把 onmount 和 useStoreStock 去掉了
    如果没影响 那确实是没必要 hook 啊 一个方法就可以了
    但是如果他这里去掉了 页面里加回来了那就看到底要抽象到什么程度了吧
    wangtian2020
        3
    wangtian2020  
       2023-12-18 14:01:27 +08:00   1
    写了三年 vue 我没用过 hooks 和 mixin
    Yumwey
        4
    Yumwey  
       2023-12-18 14:03:44 +08:00
    esm 是写法吗?

    这单纯就是写 vue 的把喜欢写 react 的代码改得更 vue 而已
    abelmakihara
        5
    abelmakihara  
       2023-12-18 14:04:07 +08:00
    还有那个单例的到底需不需要单例
    说到底还是要看需求 hook 没有更高级
    不过估计大概率是你赢了
    mxT52CRuqR6o5
        6
    mxT52CRuqR6o5  
       2023-12-18 14:06:56 +08:00
    reactive 这个 api 不算 hooks (那些 use 开头的才算),就是个单例
    liuhuihao
        7
    liuhuihao  
       2023-12-18 14:09:15 +08:00
    左侧的是标准 hooks 写法,右侧是给拆成了一个一个 export 的 方法?右侧这个写法如果能实现功能的话我理解就是一个 utils 类似的东西,不是 hooks ,右侧这种写法 watch 、onMounted 咋写呢?感觉右侧这样限制很大,不是 hooks 写法了已经。很明显你的抽象方式是正确的
    chill777
        8
    chill777  
    OP
       2023-12-18 14:11:45 +08:00
    @abelmakihara
    因为我这个 hooks ,有多个组件使用。还有生命周期 hook 和其他 hook 。抽成模块就没办法复用这些逻辑。
    @horizon
    esm:就是改成 import 和 export 写法。本来直接从 hooks 取值,就行。
    我在想这种单例的写法,会有重复创建的问题吗?还有就是垃圾回收的的问题,如果我去其他使用这个变量的组件,变量会重新初始化吗?
    chenliangngng
        9
    chenliangngng  
       2023-12-18 14:12:37 +08:00
    如果你是从 vue2 转到 vue3 ,那可能觉得第一种是对的

    但是如果你 vue2 ,vue3 ,react 都写过,那就知道第二种才是那个合适的

    为什么?
    因为 hooks 存在的意义就是为了逻辑拆封,自定义的 hooks 应该额外定义。但是呢你现在展示的这个代码,拆封的太细了,拆到只剩 relative 是不应该的
    chenliangngng
        10
    chenliangngng  
       2023-12-18 14:13:37 +08:00
    @chenliangngng relative => reactive
    chenliangngng
        11
    chenliangngng  
       2023-12-18 14:14:24 +08:00
    @chenliangngng 拆封=>拆分
    liuhuihao
        12
    liuhuihao  
       2023-12-18 14:16:21 +08:00
    @chill777 明显是你的写法更合理啊,我很好奇右侧那种写法 生命周期一类的咋写的,写在页面逻辑里吗?那还抽象个锤子。另外多个页面 import 的话,hooks 写法每次都是 return 一个新的对象,不会互相影响,右侧那种写法不就变成单例的了么,各个页面互相影响
    liuhuihao
        13
    liuhuihao  
       2023-12-18 14:18:14 +08:00
    @chenliangngng #10 你再仔细看看 lz 的代码,并不是只拆分到 reactive ,他左侧整张图都是一个 hooks 只不过底部的 return 没有截上,我认为 lz 的写法是没有问题的,右侧的抽象反而是抽象了个寂寞
    liuhuihao
        14
    liuhuihao  
       2023-12-18 14:21:35 +08:00
    我理解的 hooks 拆封
    export default function (deps) {
    const data = ref('')
    const data2 = ref('')

    const doSomeThing = ()=>{
    XXX
    }

    watch(deps, XXX)

    onMounted(()=>{
    XXX
    })

    return {data,data2,doSomeThing}
    }
    abelmakihara
        15
    abelmakihara  
       2023-12-18 14:22:56 +08:00   1
    @chill777 就单论这个图片里的话
    如果这个 obj 是单例的话 下面那个方法很明显也是获取 obj 的 我会扔到 store 里
    如果不是单例的那就 hook
    如果这个方法会有不同 hook 用? 还可以把这些方法单独抽个 service
    --
    当然不会初始化了 这就是全局通用的
    Zzzz77
        16
    Zzzz77  
       2023-12-18 14:23:13 +08:00
    这有啥争议,左边对
    Huelse
        17
    Huelse  
       2023-12-18 14:38:24 +08:00
    右边的问题很大,既不单例,也不 esm ,堪称屎山之基。
    jspatrick
        18
    jspatrick  
       2023-12-18 15:20:36 +08:00
    是 hooks 就该用闭包(左),不是 hooks 没理由用 reactive (右),也可能是我业务场景不够丰富,目前没遇到过右边这种情况
    horizon
        19
    horizon  
       2023-12-18 15:41:15 +08:00
    @chill777 #8
    不会重复创建,不会回收,不会重新初始化。
    所以右侧这个写法没法复用。。
    a632079
        20
    a632079  
       2023-12-18 20:16:12 +08:00
    1. 这和 esm 没关系。
    2. Vue 里面的响应式包 `@vue/reactivity`,比如 reactive 啥的都可以脱离 setup 使用。所以他第二种做法是可以的。

    P.S pinia 里面的 introduce 里面就有提到,为啥要用它,不用第二种(直接使用 reactive 做状态管理)。其中最大的优势就是 SSR 友好。https://pinia.vuejs.org/introduction.html#Why-should-I-use-Pinia-
    chill777
        21
    chill777  
    OP
       2023-12-18 20:49:05 +08:00
    @a632079
    1. ?一堆 export ,不是 esm 写法?
    2. 这里是讨论逻辑复用,不是全局状态管理。
    a632079
        22
    a632079  
       2023-12-18 21:00:06 +08:00
    @chill777 #21 1. 我可以 export {} 也可以 module.export = {}。暴露一个 JS 对象出来而已,我觉得直接称呼 ESM 不妥当。
    2. 全局状态管理里面没有 dispatch 的概念吗?这是不是一种逻辑复用呢?

    3. 是你问的:“所以这种做法是可以的吗?”。我就这句做回答:“是可以的”。所以有什么问题呢?

    如果你问是否是合理的话:此模块涉及生命周期的话,抽象成组合式 API 当然是更合适的。其他情况的话,结论就是都可以。看你们团队的喜好。
    leokun
        23
    leokun  
       2023-12-18 21:01:43 +08:00   1
    这两个写法有根本性区别,左侧的每个组件调用都可以获得全新的 chartDataObj ,右侧是所有组件共享一个 chartDataObj 。

    左边其实是这样的
    https://rollupjs.org/repl/?version=4.9.1&shareable=JTdCJTIyZXhhbXBsZSUyMiUzQW51bGwlMkMlMjJtb2R1bGVzJTIyJTNBJTVCJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCUyMCU1QyUyMi4lMkZhLmpzJTVDJTIyJTVDbmltcG9ydCUyMCUyMCU1QyUyMi4lMkZiLmpzJTVDJTIyJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0F0cnVlJTJDJTIybmFtZSUyMiUzQSUyMm1haW4uanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyZXhwb3J0JTIwY29uc3QlMjB1c2VDaGFydERhdGFPYmolM0QoKSUzRCUzRSU3QiU1Q24lMjAlMjBjb25zdCUyMGNoYXJ0RGF0YU9iaiUzRCU3QiU1Q24lMjAlMjAlMjAlMjBuYW1lJTNBMSU1Q24lMjAlMjAlN0QlNUNuJTIwJTIwcmV0dXJuJTIwY2hhcnREYXRhT2JqJTVDbiU3RCU1Q24lMjIlMkMlMjJpc0VudHJ5JTIyJTNBZmFsc2UlMkMlMjJuYW1lJTIyJTNBJTIyaG9vay5qcyUyMiU3RCUyQyU3QiUyMmNvZGUlMjIlM0ElMjJpbXBvcnQlMjAlN0J1c2VDaGFydERhdGFPYmolN0QlMjBmcm9tJTIwJTVDJTIyLiUyRmhvb2suanMlNUMlMjIlNUNuY29uc29sZS5sb2codXNlQ2hhcnREYXRhT2JqKCkpJTIyJTJDJTIyaXNFbnRyeSUyMiUzQWZhbHNlJTJDJTIybmFtZSUyMiUzQSUyMmEuanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyaW1wb3J0JTIwJTdCdXNlQ2hhcnREYXRhT2JqJTdEJTIwZnJvbSUyMCU1QyUyMi4lMkZob29rLmpzJTVDJTIyJTVDbmNvbnNvbGUubG9nKHVzZUNoYXJ0RGF0YU9iaigpKSUyMiUyQyUyMmlzRW50cnklMjIlM0FmYWxzZSUyQyUyMm5hbWUlMjIlM0ElMjJiLmpzJTIyJTdEJTVEJTJDJTIyb3B0aW9ucyUyMiUzQSU3QiUyMm91dHB1dCUyMiUzQSU3QiUyMmZvcm1hdCUyMiUzQSUyMmlpZmUlMjIlN0QlMkMlMjJ0cmVlc2hha2UlMjIlM0FmYWxzZSU3RCU3RA==

    右边其实是这样的:
    https://rollupjs.org/repl/?version=4.9.1&shareable=JTdCJTIyZXhhbXBsZSUyMiUzQW51bGwlMkMlMjJtb2R1bGVzJTIyJTNBJTVCJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCUyMCU1QyUyMi4lMkZhLmpzJTVDJTIyJTVDbmltcG9ydCUyMCUyMCU1QyUyMi4lMkZiLmpzJTVDJTIyJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0F0cnVlJTJDJTIybmFtZSUyMiUzQSUyMm1haW4uanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyZXhwb3J0JTIwY29uc3QlMjBjaGFydERhdGFPYmolM0QlN0IlNUNuJTIwJTIwbmFtZSUzQTElNUNuJTdEJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0FmYWxzZSUyQyUyMm5hbWUlMjIlM0ElMjJob29rLmpzJTIyJTdEJTJDJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCU3QmNoYXJ0RGF0YU9iaiU3RCUyMGZyb20lMjAlNUMlMjIuJTJGaG9vay5qcyU1QyUyMiU1Q25jb25zb2xlLmxvZyhjaGFydERhdGFPYmopJTIyJTJDJTIyaXNFbnRyeSUyMiUzQWZhbHNlJTJDJTIybmFtZSUyMiUzQSUyMmEuanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyaW1wb3J0JTIwJdCY2hhcnREYXRhT2JqJTdEJTIwZnJvbSUyMCU1QyUyMi4lMkZob29rLmpzJTVDJTIyJTVDbmNvbnNvbGUubG9nKGNoYXJ0RGF0YU9iaiklMjIlMkMlMjJpc0VudHJ5JTIyJTNBZmFsc2UlMkMlMjJuYW1lJTIyJTNBJTIyYi5qcyUyMiU3RCU1RCUyQyUyMm9wdGlvbnMlMjIlM0ElN0IlMjJvdXRwdXQlMjIlM0ElN0IlMjJmb3JtYXQlMjIlM0ElMjJpaWZlJTIyJTdEJTJDJTIydHJlZXNoYWtlJTIyJTNBZmFsc2UlN0QlN0Q=

    chill777
        24
    chill777  
    OP
       2023-12-18 21:10:57 +08:00
    @a632079
    1. vue3 ?浏览器?有用 cjs 模块的?
    2. 不是! dispatch 每一步得到的值基本都不一样,组件逻辑复用和全局状态管理根本不是一个东西。
    3. 什么叫抽象成组合式 API ?
    a632079
        25
    a632079  
       2023-12-18 21:27:12 +08:00
    @chill777 #24
    1. 我要表达的意思是,这个和你用 ESM ,CJS 无关。他这种用法就相当于声明了个 JS 对象,然后 export 出去,这是很明显的单例用途把。只不过放在了模块上了。
    2. 争论点,或者说差异就在是否有必要使用生命周期上。如果单例够用的话,2 能用。如果单例会污染数据的话,那肯定是抽象 hooks ,或者说组合式 API 更合理。这点我的看法是和 #2 一样的。
    3. 抽象(解耦)不就是和耦合对立的?一块通用逻辑提取出来,不叫抽象一个组件,一个模块出来吗?
    chill777
        26
    chill777  
    OP
       2023-12-18 21:32:10 +08:00
    @Yumwey
    1. esm 写法。esm 在前面是定语,用来修饰写法的。
    2. vue3 是推荐这种写法的<https://cn.vuejs.org/guide/reusability/composables.html#comparisons-with-other-techniques>
    chill777
        27
    chill777  
    OP
       2023-12-18 21:41:48 +08:00
    @a632079
    1. export 出去就是 esm 的写法。hooks 是种写法,拆开各个 export 出去也是写法,我称为 esm 写法没有任何问题。
    2. 争这是逻辑复用,每个组件都是独立的,2 不能使用,会相互影响。
    3. 组合 api 是 vue3 自己提供的,什么时候轮到你来抽象了。
    麻烦把基本概念,逻辑理清在说话。
    请勿复言,竖子不足与谋。
    lscho
        28
    lscho  
       2023-12-18 22:03:34 +08:00
    自信点。。。右边问题很大
    wakarimasen
        29
    wakarimasen  
       2023-12-19 00:49:08 +08:00 via Android
    ESM 写法好像真是你自创的说法。
    然后第二种写法在一些情况下确实会有 bug
    iPhone15
        30
    iPhone15  
       2023-12-19 01:33:43 +08:00
    建议用第一种,若要共享数据,可以用下面的工具函数创建一个单例。
    https://vueuse.org/shared/createSharedComposable/#createsharedcomposable

    它是利用 vue3 提供的 effectScope 能力实现的
    zhhbstudio
        31
    zhhbstudio  
       2023-12-19 09:31:33 +08:00
    首先,你的代码是我比较常用的写法

    回复 #8
    "esm:就是改成 import 和 export 写法。"
    你的代码最上边不也 import 了最下边不也 export 一个 useHook 出去,你这也是 esm 写法。

    回复 #9
    我刚好都写过一点,第二种合适的情况是项目大,做成工具函数可多复用吧,比如 emptyData 可以接收一个参数,然后清空,现在代码也是有问题的。

    另外:我也赞成 #13 #14 说法
    #17 +1

    #21
    纯粹的逻辑复用(比如上边提到的 emptyData ),我理解应该是抽成工具函数。不然你每次闭包里都有一个新的 emptyData 。但是比如我遇到的情况是手机端和 PC 端复用,那全放 hooks 里我自己觉得挺好。

    如果有错误的地方还请各位大佬不吝赐教~
    Yumwey
        33
    Yumwey  
       2023-12-19 14:37:56 +08:00
    @chill777 我也喜欢 hooks 写法的... 推荐是一回事,没咋写过 react 的 vue 前端是大概率不习惯 hooks 写法的vue 我记得也有个 hooks 库来着,一时间忘了
    jerrry
        34
    jerrry  
       2023-12-20 11:14:48 +08:00
    吐嘈一下你们的命名,又是 data 、又是 obj 的
    chill777
        35
    chill777  
    OP
       2023-12-20 13:27:38 +08:00
    @jerrry #34
    组内命名规范:reactive 变量后缀统一 Obj 。函数命名需要注意可读性。
    有什么问题吗?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2732 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 30ms UTC 09:13 PVG 17:13 LAX 02:13 JFK 05:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86