EasyDSL:简化 Flutter 开发,类 TailwindCSS 的方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
gydi
V2EX    分享创造

EasyDSL:简化 Flutter 开发,类 TailwindCSS 的方案

  •  
  •   gydi
    zzzgydi 2024-01-12 13:51:47 +08:00 3457 次点击
    这是一个创建于 708 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    最近在写 Flutter ,感觉一个 padding 都要写一堆,比之前写 web 是要繁琐一点。虽然也有看到一些方案,比如包一层通过属性来设置各种样式。但是好像没有看到类似 TailwindCSS 那样,直接一个 className 字符串就可以写一堆的方案。(如果已经有了话,也可以评论告知一下)

    技术方案

    一开始想做这个的时候,脑子里只有通过代码生成的方式,后来想想也可以通过运行时的方式。运行时方案暂时没实现,后续可以两种方式都实现,或者 dev 的时候用运行时方式,prod 的时候用代码生成的方式,说到这个脑子里就想到了 vite:)。下面就只说说代码生成的方式。

    一个很容易想到的方案就是,对外暴露一个 Div widget ,然后一个 className 属性,build 的时候通过一个 map 去实现,className 到对应 widget 的映射。

    基于这个简单的原理,就可以去琢磨 dart 的代码生成了。搞懂 dart 的 build, build_runner, analyzer 之类的包之后,就敲定方案为:先遍历所有 dart 代码找到所有的 className 字符串,然后通过一个注解锚定一个生成文件的位置,然后进行代码生成。

    项目进展

    仓库地址: https://github.com/zzzgydi/easy_dsl

    目前已经发了俩 dart 包:easy_dsl 和 easy_dsl_gen 。

    之所以叫 DSL 而不是 Tailwind 之类的,是感觉后续还可以有更多的 DSL 设计来辅助开发。

    当前支持的一些 className 大概有:

    • flex items-center justify-center 还有特定的 row col stack
    • w-10 h-10 max-w-[100] min-h-[100] p-10, m-10
    • bg-red-100 bg-[#000000] bg-black/10
    • border rounded-md border-red-100
    • aspect-video opacity-10
    • 还有自己常用的 SafeArea 相关的 safe-t safe

    未来还会逐渐添加更多。

    遇到一些问题

    首先是热更新的问题,.g.dart文件的变化似乎不会再次引起 hot reload ,所以用户得 ctrl+s 保存两次,样式变更才能展示出来。这个问题目前没想好咋搞。

    另外一个是,变更 className 之后就会导致 map 里找不到对应的 widget ,进而导致首次热更新的时候 widget 会闪烁(样式变化嘛)。然后得第二次热更新时候样式才能生效,两次时间差的体感还是很明显的。为了解决这个闪烁的问题,简单的处理是在开发时,用编辑距离去判断两个 className 是否可能匹配,这样虽然不能 fix 两次保存才生效的问题,但是可以部分 fix 大幅度闪烁的问题(不是完全 fix )。

    最后

    我刚玩 Flutter 不久,希望写 Flutter 的同行路过可以给点意见和建议。感兴趣的可以给仓库点个 star ,来点 issue 反馈和 pr 就更好了。

    11 条回复    2024-01-12 16:33:35 +08:00
    hiscc
        1
    hiscc  
       2024-01-12 13:53:47 +08:00   1
    不错不错,支持
    Carlgao
        2
    Carlgao  
       2024-01-12 14:11:51 +08:00
    问一下 clash-verge 彻底不搞了吗?
    ZGame
        3
    ZGame  
       2024-01-12 14:41:23 +08:00
    不好用 ,你这不就是原子化 css 吗? 嵌套麻烦可以和 react 一样做一个复合组件 ,然后定义 props 传递给用户用啊...
    1438010826
        4
    1438010826  
       2024-01-12 14:42:29 +08:00   1
    有点意思,感觉是个有意思的方向
    gydi
        5
    gydi  
    OP
      nbsp;2024-01-12 15:01:16 +08:00
    @Carlgao 不弄了,换别的玩了
    gydi
        6
    gydi  
    OP
       2024-01-12 15:02:17 +08:00
    @ZGame 那就是我说的运行时方案,有很多类似的。我这个的方向就是在 flutter 里搞类似原子 css 那套。
    jenhe
        7
    jenhe  
       2024-01-12 15:26:36 +08:00
    你这响应式布局怎么处理?
    zuosiruan
        8
    zuosiruan  
       2024-01-12 15:29:34 +08:00
    @Carlgao #2
    @gydi #5 可惜
    gydi
        9
    gydi  
    OP
       2024-01-12 15:33:23 +08:00
    @jenhe flex 的话,生成的代码就是 Row 和 Column 这些。还是说响应式是指屏幕宽高变化哪些吗,哪些还没整。
    jenhe
        10
    jenhe  
       2024-01-12 16:00:45 +08:00
    @gydi #9 嗯,就是指宽高,一般都用 flutter_screenutil 这种方案
    gydi
        11
    gydi  
    OP
       2024-01-12 16:33:35 +08:00
    @jenhe #10 如果要拿屏幕宽高做响应式的话,好像还有点复杂。如果只拿父级做响应式的话,用 LayoutBuilder 应该好搞。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2515 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 04:07 PVG 12:07 LAX 20:07 JFK 23:07
    Do have faith in what you're doing.
    ubao msn 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