终于把 Vue 的 Dialog 给整舒服了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shakaraka
0D
V2EX    Vue.js

终于把 Vue 的 Dialog 给整舒服了

  •  1
     
  •   shakaraka
    PRO
    2022-08-11 15:26:06 +08:00 1907 次点击
    这是一个创建于 1157 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前流行的弹窗,不管是

    <dialog visible="visible"> <user-dialog /> </dialog> 

    还是

    <template> <dialog visible="visible"></dialog> </template> <script> visible = false open(){ this.visible = true } close(){ this.visible = true } </script> 

    都难受至极。

    第一种写法

    • 在使用 dialog 的时候,dialog 就已经加载好了,但是我还不需要,所以造成不必要的资源浪费(可忽略),以及在代码里看着这堆东西太不优雅了
     <dialog ref="dialog1" :visible="dialog1" /> <dialog ref="dialog2" :visible="dialog2" /> <dialog ref="dialog3" :visible="dialog3" /> <dialog ref="dialog4" :visible="dialog4" /> ...... 
    • visible 会留在调用组件里,调用者有 N 个 dialog 就有 N 个变量
    data(){ return { dialog1: false, dialog2: false, dialog3: false, ...... } } 
    • 想在关闭 dialog 的时候做一些事情很难受,要么 watch dialog1~N 这个变量,要么给所有 dialog 写<dialog @close="close" />
    • 在关闭弹窗时,接收返回的变量很难受
      <dialog :visible.sync="visible"> <user-dialog @close="close" /> </dialog> data(){ return { visible: true } } close(event){ console.log(event) this.visible = false } 

    第二种写法

    • 一旦引入组件,组件便开始 mount 了,生命周期也执行了,如果调用者引入了 N 个 dialog ,那性能可想而知,还不如第一种写法

    • 因失去了生命周期的特性,导致关闭弹窗的时候需要你自己重置数据,做清理

    • 而且你开不能利用生命周期来做数据加载,因为你还没打开弹窗,90%的业务场景是没必要加载数据的,所以你还要在 open 里自己加载

    • 还有一些问题我暂时想不起来,先略吧

    忍了好久了,终于把 https://material.angular.io/components/dialog/overview 的 dialog 给挪过来了,所说不太完美,但是至少满足我的痛点了。

    使用文档可以看我写的demo,API 参考的话可以看Dialog | Angular Material

    各位如果也有同样的痛苦的话,可以 fork 到自己项目里去改一下就可以用了。

    写得不是很完美,仅作为一个想法、思路。

    ps:真的想吐槽手动初始化 Vue 这个过程,难受至极,离开了文档的操作,啥也不是。

    swordne
        1
    swordne  
       2022-08-11 16:18:22 +08:00
    vant 的 dialog 还行啊。
    shakaraka
        2
    shakaraka  
    OP
    PRO
       2022-08-11 16:24:48 +08:00
    @swordne #1 vant 的调用的方式,还是没逃脱我上文说的这两种写法
    corcd
        3
    corcd  
       2022-08-15 03:35:17 +08:00 via iPhone
    你可以挂 ref 然后把 visible 状态维持在 dialog 内部,用 open 和 close 方法去修改 visible 就好了,就是不太符合数据驱动的思路
    shakaraka
        4
    shakaraka  
    OP
    PRO
       2022-08-15 03:43:42 +08:00
    @corcd #3 你这种就是我列出的第二种写法,弊端我上文写了。还是没人能跳出这两种思路
    gausszhou
        5
    gausszhou  
       2022-08-16 09:49:57 +08:00
    我这之前是直接用了 v-if 了, 然后 在 dialog 内 created 和 mounted 进行 接口数据调用和 ref 操作 /(ㄒoㄒ)/~~
    chenjiangui998
        6
    chenjiangui998  
       2022-08-28 01:59:27 +08:00
    直接用 v-if 代替 visible 啊, 关闭直接 emit('close'), 不用管是否实际关闭
    shakaraka
        7
    shakaraka  
    OP
    PRO
       2022-08-28 03:09:56 +08:00
    @chenjiangui998 #6

    这么做的话其实和上述第一种写法没什么区别。

    假设 A 里面有 B ,C 两个 dialog:

    传值的的时候在 A 里定义一个变量去传递给下级,有 N 个 dialog 就会有 N 个变量,不优雅且难管理。

    假如 B ,C 两个都是使用同一个变量的话,加上 ts 的话这个变量定义会变得又臭又长,例如 dialogData: TypeB | TypeC | .... = null ,你需要手动管理这个变量,用起来也会很糟心。

    其实作为初始化 dialog 的 data 是没必要在当前组件定义变量的,太嗦了。

    接收 dialog 事件的问题如上。

    -----------

    我目前接手过的 vue 项目 100%都是上述两种写法,如果写的人有心去写好的话,那也问题不大(也难受就是了),但不知道什么原因,每个地方都是写的流水账一样,一个 dialog 有 n 个需要传递的变量,还有 n 个接收 event 的方法,还没类型,全写在父组件上,父组件还不只一个 dialog ,不知道是不是 vue 就是推崇这种写法的还是怎么的,看到 vue 主流的的 ui 都是这样的

    -----------

    你可以看下 https://material.angular.io/components/dialog/overview ,做的很优雅,对你应该挺有帮助的
    chenjiangui998
        8
    chenjiangui998  
       2022-08-28 14:14:43 +08:00
    @wunonglin 看了, 这个相当于实现了个公用 dialog, 切换内部内容, 而且要用 rxjs 和事件驱动, 我觉得不如直接状态驱动简单干脆,
    ```
    const dialog = {
    show: true,
    components: 'xxx1',

    }

    <dialog :visible="dialog.show">
    <component></component>
    </dialog>

    ```
    chenjiangui998
        9
    chenjiangui998  
       2022-08-28 14:16:53 +08:00
    @wunonglin
    看了, 这个相当于实现了个公用 dialog, 切换内部内容, 而且要用 rxjs 和事件驱动, 我觉得不如直接状态驱动简单干脆,
    ```
    const dialog = {
    show: true,
    components: 'xxx1',
    props: {}
    }

    <dialog :visible="dialog.show" @close="xxx">
    <component :is="dialog.components" v-bind="props"></component>
    </dialog>

    ```
    刚回车了, 我觉得这个和你发的那个没啥区别, 而且还是状态驱动的
    shakaraka
        10
    shakaraka  
    OP
    PRO
       2022-08-28 14:18:07 +08:00
    @chenjiangui998 #8 确实是简单了。不过太不优雅了
    shakaraka
        11
    shakaraka  
    OP
    PRO
       2022-08-28 14:21:32 +08:00
    @chenjiangui998 #9 目前我在公司内部用着我写的这个了,体验和 ng 的一样,还不错。后面打算去掉 element ,自己实现个 layout 层,这样体验会更好
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5604 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 50ms UTC 07:53 PVG 15:53 LAX 00:53 JFK 03:53
    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