V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
gydi
V2EX  ›  分享创造

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

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

    背景

    最近在写 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  
       342 天前   ❤️ 1
    不错不错,支持👍
    Carlgao
        2
    Carlgao  
       342 天前
    问一下 clash-verge 彻底不搞了吗?
    ZGame
        3
    ZGame  
       342 天前
    不好用 ,你这不就是原子化 css 吗? 嵌套麻烦可以和 react 一样做一个复合组件 ,然后定义 props 传递给用户用啊...
    1438010826
        4
    1438010826  
       342 天前   ❤️ 1
    有点意思,感觉是个有意思的方向
    gydi
        5
    gydi  
    OP
       342 天前
    @Carlgao 不弄了,换别的玩了
    gydi
        6
    gydi  
    OP
       342 天前
    @ZGame 那就是我说的运行时方案,有很多类似的。我这个的方向就是在 flutter 里搞类似原子 css 那套。
    jenhe
        7
    jenhe  
       342 天前
    你这响应式布局怎么处理?
    zuosiruan
        8
    zuosiruan  
       342 天前
    @Carlgao #2
    @gydi #5 可惜
    gydi
        9
    gydi  
    OP
       342 天前
    @jenhe flex 的话,生成的代码就是 Row 和 Column 这些。还是说响应式是指屏幕宽高变化哪些吗,哪些还没整。
    jenhe
        10
    jenhe  
       342 天前
    @gydi #9 嗯,就是指宽高,一般都用 flutter_screenutil 这种方案
    gydi
        11
    gydi  
    OP
       342 天前
    @jenhe #10 如果要拿屏幕宽高做响应式的话,好像还有点复杂。如果只拿父级做响应式的话,用 LayoutBuilder 应该好搞。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3238 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:04 · PVG 08:04 · LAX 16:04 · JFK 19:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.