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

准备写一个关于 Vue 的系列文章

  •  
  •   yetrun · 300 天前 · 1413 次点击
    这是一个创建于 300 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在开发前端项目的时候,用的都是 Vue 3 框架。Vue 挺好用,同时我也发现使用 Vue 要注意的细节还是挺多的,因此我将平时积累的遇到的坑都打包记在笔记里,现在想要整理一下分享出来。一是为我的博客增增彩,很久没更新了而且没什么人气;二是将自己遇到的问题分享出来并加入讨论,分享也能让我更好的成长。有些问题我也有些困惑,所以通过分享和讨论看能否得到更标准的解决方案。

    我大体的分享思路是:

    1. 关于 watch 的,发现在使用它时还有很多注意的点的。
    2. 关于 Vue router 的,主要关于对话框路由怎么在 Vue 中实现,比市面上的其他文章还多了一个环节。
    3. 其他有关的话题,比如涉及到异步竞争的,等等。

    由于我最近还是挺忙的,第一次分享的时间暂定在本周六( 7 月 8 日),并在之后尽量保持一周一更的节奏。

    OK ,欢迎大家来捧场、讨论、指正和参考。我的博客小家是:

    blog.yet.run

    第 1 条附言  ·  294 天前

    第一篇写好了,有关我使用 watch(route) 遇到的问题,不知道有没有人和我遇到同样的问题。

    Vue 3 避坑指南(一):避免使用 watch(route)

    第 2 条附言  ·  280 天前

    第二篇和第三篇也写好了。第二篇上周写好忘记发了,这次一起:

    第 3 条附言  ·  273 天前
    第 4 条附言  ·  266 天前
    第五篇:[Vue 3 避坑指南(五):有关范型组件的支持 ]( http://blog.yet.run/2023/08/06/vue-3-generic-component/)
    第 5 条附言  ·  259 天前

    Vue 3 避坑指南(五):缺乏范型组件的支持 补充了 Vue 3 中实现范型组件的方案

    第 6 条附言  ·  252 天前
    17 条回复    2023-08-15 09:28:43 +08:00
    utfs8889
        1
    utfs8889  
       300 天前
    wow~ 围观支持!
    可以的话,也欢迎 op 同步一份内容到 [WRITE-BUG 数字空间] 上呀~
    yetrun
        2
    yetrun  
    OP
       294 天前
    @utfs8889 你这是一个代码共享和协作的平台吗?能否发一个例子给我看看额?
    agileago
        3
    agileago  
       265 天前
    大兄弟,试试 vue3-oop https://github.com/agileago/vue3-oop, 遇到的问题都不是问题
    yetrun
        4
    yetrun  
    OP
       265 天前
    @agileago 感觉很复杂啊,这是不是为解决一个问题引入了另一个问题?
    agileago
        5
    agileago  
       265 天前
    啊,真的假的,怎么会觉得复杂呢?
    yetrun
        6
    yetrun  
    OP
       265 天前
    @agileago 可能是我没理解你框架的想法吧。我只是想要用纯粹的 Vue 3 去写应用就行了,现实中遇到坑了需要避掉就记录下来,加深下感受。但你的框架里的东西,继承 VueComponent<FooProps>,然后用到各种注解,说实话不知道想要达到什么目的。

    如果说继承 VueComponent<FooProps> 是编写一个组件,各种注解是定义这个组件的各种部分,如 data 、methods 、生命周期等,这样不就是退化到 Vue 2 的写法吗?体验了 Vue 3 setup 带来的自由和组织方式,Vue 2 的写法再也回不去了。

    另外说到的依赖注入,我写后端都不用的东西,我写前端就更加用不上了。体会不到依赖注入的目的和它用到的场景。我看到了你的标题里有 Angular 依赖注入,也许对 Angular 开发者更容易理解一点吧,或者 Spring 开发者?
    agileago
        7
    agileago  
       265 天前
    跟 vue2 完全没啥关系,我是想达到一种自然的写法,你想想,你写的代码逻辑核心都在处理什么?难道不是处理变量和该变变量的函数么? 把变量和函数组织在一起的不就是类么?

    下面这是个简单逻辑

    ```
    class Count {
    count = 1
    add = () => this.count++
    }
    ```

    那对于界面开发,需要有渲染函数的存在, 另外得知道他是一个 vue 组件, 那就演变成下面这样子的设计

    ```
    class Count extends VueComponent {
    count = 1
    add = () => this.count++

    render() {
    return <div onClick={this.add}>{this.count}</div>
    }
    }
    ```

    那假如数据变了, 我要通知框架我要刷新了,那我怎么告诉框架呢?就变成下面的设计了,给这个变量标记一下是可变变量,变化的时候框架会自动更新



    ```
    class Count extends VueComponent {
    @Mut() count = 1
    add = () => this.count++

    render() {
    return <div onClick={this.add}>{this.count}</div>
    }
    }
    ```


    这个时候随着组件逻辑的增加,导致组件代码激增,你想把代码拆分出去(类似 hook), 更好维护, 那代码就演变成下面这样子


    ```
    // 服务 类似 useHooks
    class CountService extends VueService {
    @Mut() count = 1
    add = () => this.count++
    }

    class Count extends VueComponent {
    countService = new CountService()

    render() {
    const { countService } = this
    return <div onClick={countService.add}>{countService.count}</div>
    }
    }
    ```

    但是你拆分逻辑不可能只有这一个 service, 就像你拆分成 useHook 一样, 当这些服务越来越多,并且之间会相互依赖,比如, B 依赖 A ,C 依赖 B ,C 又依赖 A , 那你得代码只能这样写

    ```
    const A = useHookA()
    const B = useHookB(A)
    const C = useHookC(B, A)
    ```

    这个时候加入某个服务的依赖调整了,你要去调整这一坨必须按顺序初始化的代码,是非常烦人的, 这个时候依赖注入就出场收拾残局了

    ```
    class A extends VueService {
    }

    @Injectable()
    class B extends VueService {
    constructor(private a: A) {
    super()
    }
    }

    @Injectable()
    class C extends VueService {
    constructor(private a: A, private b: B) {
    super()
    }
    }


    @Component()
    class Count extends VueComponent {
    constructor(private a: A, private b: B, private c: C) {
    super()
    }

    render() {
    const { a, b, c } = this
    return <div onClick={countService.add}>{countService.count}</div>
    }
    }
    ```


    代码是一步一步演化的
    agileago
        8
    agileago  
       265 天前
    包括你说的泛型组件,很轻易就实现了

    [Imgur]( )
    yetrun
        9
    yetrun  
    OP
       264 天前
    @agileago 我去消化一下。前一半部分我理解了,其中用到 TSX 写组件。然后这样也可以实现范型组件了,没错。但是有一个疑问,用 Vue 本身的形式是否也可以完全用 TSX 而不用单文件组件的方式写组件呢?那这样的话用 Vue 本身的形式是否就可以做到范型组件了?

    const Comp = defineComponent({
    setup () {
    return <div>...</div> # TSX
    }
    })
    agileago
        10
    agileago  
       264 天前
    vue 本身的形式连外置声明一个属性类型都困难,更别说实现泛型组件了,这么说吧,tsx 比模版强太多了,再加上 ts 官方支持,写起来爽飞天,另外模板现在的黑魔法越来越多, 为了补足模板的功能,你看官方出了多少工具函数, 什么 defineProps, defineEmits ....., 为了 reactive 的结构又出了 toRefs.....等等,现在用模版心智负担太重,而 vue3-oop 让你忘记什么 ref, reactive,就是强调用自然符合直觉的写法来做界面开发
    agileago
        11
    agileago  
       264 天前
    另外你说的 vue3 不能声明 slots 的类型致命缺陷,vue3-oop 同样解决

    https://s1.ax1x.com/2023/08/08/pPVTA2D.png
    yetrun
        12
    yetrun  
    OP
       264 天前
    @agileago 关于你所说,我再研究研究。我怎么记得 Vue 3 有用 TSX 支持范型组件的写法,先等我几天。
    yetrun
        13
    yetrun  
    OP
       259 天前
    @agileago 有关 Vue 3 中实现范型组件的方案,我做了补充。对于你给出的例子,我有两点疑惑:

    1. defaultProps: ComponentProps<AProps<any>> 这一行是作什么的?
    2. return <A<ItemA> ... /> 这里的 <ItemA> 必须要有吗?
    agileago
        14
    agileago  
       258 天前
    @yetrun 哈哈

    1. defaultProps 是 vue 需要的属性声明啊,https://cn.vuejs.org/api/options-state.html#props 这里叫 defaultProps 是因为类组件一般都是这个名字的 https://zh-hans.react.dev/reference/react/Component#static-defaultprops


    2. 当然可以, 我这样写是让你一眼能看出来支持泛型 https://imgse.com/i/pPKqifH
    yetrun
        16
    yetrun  
    OP
       257 天前
    @agileago 嗯,那就行了,总体感觉就挺好了
    agileago
        17
    agileago  
       257 天前 via iPhone
    @yetrun 还能找出来致命缺陷么😄
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1085 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:38 · PVG 02:38 · LAX 11:38 · JFK 14:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.