V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
chill777
V2EX  ›  Vue.js

vue3 hooks 可以转为 esm 写法?

  •  
  •   chill777 · Dec 18, 2023 · 3999 views
    This topic created in 861 days ago, the information mentioned may be changed or developed.

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

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

    Supplement 1  ·  Dec 18, 2023
    其实我只是想吐槽一下工作遇到的奇葩而已。

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

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

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

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

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

    为什么?
    因为 hooks 存在的意义就是为了逻辑拆封,自定义的 hooks 应该额外定义。但是呢你现在展示的这个代码,拆封的太细了,拆到只剩 relative 是不应该的
    chenliangngng
        10
    chenliangngng  
       Dec 18, 2023
    @chenliangngng relative => reactive
    chenliangngng
        11
    chenliangngng  
       Dec 18, 2023
    @chenliangngng 拆封=>拆分
    liuhuihao
        12
    liuhuihao  
       Dec 18, 2023
    @chill777 明显是你的写法更合理啊,我很好奇右侧那种写法 生命周期一类的咋写的,写在页面逻辑里吗?那还抽象个锤子。另外多个页面 import 的话,hooks 写法每次都是 return 一个新的对象,不会互相影响,右侧那种写法不就变成单例的了么,各个页面互相影响
    liuhuihao
        13
    liuhuihao  
       Dec 18, 2023
    @chenliangngng #10 你再仔细看看 lz 的代码,并不是只拆分到 reactive ,他左侧整张图都是一个 hooks 只不过底部的 return 没有截上,我认为 lz 的写法是没有问题的,右侧的抽象反而是抽象了个寂寞
    liuhuihao
        14
    liuhuihao  
       Dec 18, 2023
    我理解的 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  
       Dec 18, 2023   ❤️ 1
    @chill777 就单论这个图片里的话
    如果这个 obj 是单例的话 下面那个方法很明显也是获取 obj 的 我会扔到 store 里
    如果不是单例的那就 hook
    如果这个方法会有不同 hook 用? 还可以把这些方法单独抽个 service
    --
    当然不会初始化了 这就是全局通用的
    Zzzz77
        16
    Zzzz77  
       Dec 18, 2023
    这有啥争议,左边对
    Huelse
        17
    Huelse  
       Dec 18, 2023
    右边的问题很大,既不单例,也不 esm ,堪称屎山之基。
    jspatrick
        18
    jspatrick  
       Dec 18, 2023
    是 hooks 就该用闭包(左),不是 hooks 没理由用 reactive (右),也可能是我业务场景不够丰富,目前没遇到过右边这种情况
    horizon
        19
    horizon  
       Dec 18, 2023
    @chill777 #8
    不会重复创建,不会回收,不会重新初始化。
    所以右侧这个写法没法复用。。
    a632079
        20
    a632079  
       Dec 18, 2023
    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
       Dec 18, 2023
    @a632079
    1. ?一堆 export ,不是 esm 写法?
    2. 这里是讨论逻辑复用,不是全局状态管理。
    a632079
        22
    a632079  
       Dec 18, 2023
    @chill777 #21 1. 我可以 export {} 也可以 module.export = {}。暴露一个 JS 对象出来而已,我觉得直接称呼 ESM 不妥当。
    2. 全局状态管理里面没有 dispatch 的概念吗?这是不是一种逻辑复用呢?

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

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

    它是利用 vue3 提供的 effectScope 能力实现的
    zhhbstudio
        31
    zhhbstudio  
       Dec 19, 2023
    首先,你的代码是我比较常用的写法

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

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

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

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

    如果有错误的地方还请各位大佬不吝赐教~
    Yumwey
        33
    Yumwey  
       Dec 19, 2023
    @chill777 我也喜欢 hooks 写法的... 推荐是一回事,没咋写过 react 的 vue 前端是大概率不习惯 hooks 写法的😂vue 我记得也有个 hooks 库来着,一时间忘了
    jerrry
        34
    jerrry  
       Dec 20, 2023
    吐嘈一下你们的命名,又是 data 、又是 obj 的
    chill777
        35
    chill777  
    OP
       Dec 20, 2023
    @jerrry #34
    组内命名规范:reactive 变量后缀统一 Obj 。函数命名需要注意可读性。
    有什么问题吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   971 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 19:54 · PVG 03:54 · LAX 12:54 · JFK 15:54
    ♥ Do have faith in what you're doing.