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

vue3 hooks 可以转为 esm 写法?

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

    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=JTdCJTIyZXhhbXBsZSUyMiUzQW51bGwlMkMlMjJtb2R1bGVzJTIyJTNBJTVCJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCUyMCU1QyUyMi4lMkZhLmpzJTVDJTIyJTVDbmltcG9ydCUyMCUyMCU1QyUyMi4lMkZiLmpzJTVDJTIyJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0F0cnVlJTJDJTIybmFtZSUyMiUzQSUyMm1haW4uanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyZXhwb3J0JTIwY29uc3QlMjBjaGFydERhdGFPYmolM0QlN0IlNUNuJTIwJTIwbmFtZSUzQTElNUNuJTdEJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0FmYWxzZSUyQyUyMm5hbWUlMjIlM0ElMjJob29rLmpzJTIyJTdEJTJDJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCU3QmNoYXJ0RGF0YU9iaiU3RCUyMGZyb20lMjAlNUMlMjIuJTJGaG9vay5qcyU1QyUyMiU1Q25jb25zb2xlLmxvZyhjaGFydERhdGFPYmopJTIyJTJDJTIyaXNFbnRyeSUyMiUzQWZhbHNlJTJDJTIybmFtZSUyMiUzQSUyMmEuanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyaW1wb3J0JTIwJTdCY2hhcnREYXRhT2JqJTdEJTIwZnJvbSUyMCU1QyUyMi4lMkZob29rLmpzJTVDJTIyJTVDbmNvbnNvbGUubG9nKGNoYXJ0RGF0YU9iaiklMjIlMkMlMjJpc0VudHJ5JTIyJTNBZmFsc2UlMkMlMjJuYW1lJTIyJTNBJTIyYi5qcyUyMiU3RCU1RCUyQyUyMm9wdGlvbnMlMjIlM0ElN0IlMjJvdXRwdXQlMjIlM0ElN0IlMjJmb3JtYXQlMjIlM0ElMjJpaWZlJTIyJTdEJTJDJTIydHJlZXNoYWtlJTIyJTNBZmFsc2UlN0QlN0Q=

    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
    自信点。。。右边问题很大
    angrylid
        29
    angrylid  
       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   ·   实用小工具   ·   2069 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:49 · PVG 08:49 · LAX 16:49 · JFK 19:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.