Ruby 这两天对 view_component 的一些感悟

jicheng1014 · 2021年12月27日 · 最后由 davidtsang 回复于 2022年01月13日 · 695 次阅读

同步发在利用 Rails 7 新搭的 blog http://blog.3qruok.com/posts/7

=======

最近在写 blog 和写 pushconfig 这个项目的时候,发现了原来排斥使用的 view_component 其实还是不错的

view_component 是 github 推出的一个 view 级别的抽象组件。

对我来说, view_component 最大的好处是帮我隔离了 view 的复杂, 将 rails 原来的 view 的各种魔法都隔离的出来, 所有的参数, 甚至包括 current_user 这种变量。在我的使用中, 但凡于 view_component 相关的对象, 都会作为 view_component 的 initialize 参数传入进去。通过这样的方式, 我可以控制 view_compnent 组件的复杂性。另外一个不错的内容来自于测试, 我可以不用依赖比较麻烦的用户登录来渲染整个页面, 之后再测试这整个页面的局部, 而是直接将变量传进去, 并且只渲染 view_component 这个对象本身生成的 html, 从而进行测试。

当然 view_component 的介绍里, 他的渲染还比 partial 的渲染快很多, 但这对于我来说, 其实影响并没有那么大。

当然 view_component 在我的使用中也遇到了两个地方不太好:

  1. 目录结构

目前我使用的是 view_component 默认推荐的目录结构, 这家伙会把 view 文件和 init 文件放在同一个目录下, 这样会造成 components 文件夹的文件比较多。看起来会比较混乱



另外一个比较尴尬的问题是 tubor stream 在 model 里直接推送 view_component 需要特殊的技巧, 因为 view_component 这家伙在渲染的时候是需要 view_context 的, 而这个东西是在 controller 的对象里才有的,而如果是在 model 里, 这里默认情况下是没有 view_context 的, 我们无法使用类似 MessageComponent.new(message: message).render_in(view_context) 的语法的, 那么怎么处理这个问题呢? 参考 https://github.com/github/view_component/issues/1106 给出的解决方案是

broadcast_append_to( 'posts', html: PostComponent.new(post: self).render_in(ActionController::Base.new.view_context) )

这个我自己没试, 只是贴在这里了

另外关于 view_component 关于 form_for form_with 的兼容性问题, 其实我没有太在官网 known issues 上看懂,回头弄明白了再补充下吧

简而言之就是 rails 版本的 react

davidtsang 回复

这个只是服务器端的 react 组件。这个玩意能否粘合一下 Javascript, 如 Stimulus 之类的 强化一下浏览器端的能力,变成纯正的服务器渲染的响应式组件呢?

像 react 这一类的,前端 html 里就一个 root 节点标签,后面的渲染完全由 react 接管了,我用起来总不放心啊.

js 前端会有性能问题。用来了都是拖泥带水的。状态管理也很复杂。调试起来要人命。js 前端带来的好处无非就是组件化,其次是样式过度更动态一点。其实用 rails 也可以实现组件化。动态方面也有成熟的方案。view components 感觉还是太复杂了。我这两天自己编写了一些代码,很简单就是实现组件化,包括数据和视图分离,css 限定作用域。用 ruby 并不难。服务器渲染客户端爽。无非就是提高生产力,不重复造轮子。

davidtsang 回复

期待你的分享,🎉

niceruby 回复

如果可行有用😅 ,我会搞成 gem 让大家玩玩,就怕自己代码太渣让人笑话。😁

需要 登录 后方可回复, 如果你还没有账号请 注册新账号