最近在写 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
safe-t safe
未来还会逐渐添加更多。
首先是热更新的问题,.g.dart
文件的变化似乎不会再次引起 hot reload ,所以用户得 ctrl+s 保存两次,样式变更才能展示出来。这个问题目前没想好咋搞。
另外一个是,变更 className 之后就会导致 map 里找不到对应的 widget ,进而导致首次热更新的时候 widget 会闪烁(样式变化嘛)。然后得第二次热更新时候样式才能生效,两次时间差的体感还是很明显的。为了解决这个闪烁的问题,简单的处理是在开发时,用编辑距离去判断两个 className 是否可能匹配,这样虽然不能 fix 两次保存才生效的问题,但是可以部分 fix 大幅度闪烁的问题(不是完全 fix )。
我刚玩 Flutter 不久,希望写 Flutter 的同行路过可以给点意见和建议。感兴趣的可以给仓库点个 star ,来点 issue 反馈和 pr 就更好了。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.