Vue Vue / React on Rails without JSON API

42thcoder · 2016年10月24日 · 最后由 cn_boris 回复于 2016年12月20日 · 9232 次阅读

RT.

最近几年,前后端分离炒得很火。作为前端圈的吃瓜群众,我一直觉得这股潮流在技术上改进不大,甚至还拖慢了开发效率,更多地是技术政治,是 Conway’s Law 的一个体现。

抛开个人喜好,层出不穷的前端框架也带了好处:组件化终于在前端流行起来了。组件化的前端框架,在视图渲染这一层,真要比 jQuery/ Bootstrap 好用太多了。

理想的情况下,我希望仍然保持 Rails 4 的经典 MVC 模式,最大限度地利用 Rails 带来的生产力; 同时也希望在 View 层使用前端的组件化框架。

  • 最大可能地复用 Rails 生态圈的现有工具,Turbolink, Asset Pipeline, Capistrano etc.
  • 极少量 JSON API. 我不喜欢每个页面,都要在服务端写代码生成一遍 JSON, 然后在前端再写一遍解析 JSON 的代码,更不想在前端搞一个有着 association 的 Model; 多数页面在需求上,也不需要异步请求数据。
  • 前端不需要做太多 hack, 不想发明一个 Vue

有同学在走类似的路么?

我和你观点类似,还不习惯这种全部 API 数据化的思路,对前期开发会增加很多开发效率的负担,尤其不熟悉 vue 的情况下。 我数次想转,但是这种强制 API 的方法和 mvc 相比,比较反人类的思考。

因此决定,原型开发和验证还是 mvc 为主,但是在设计上,考虑把 View 很好的分层,为以后分工开发走 API 路线留下空间。

这样前期开发会爽一点,加快原型开发。

rails_react 的服务器端渲染,貌似很满足需求吧

或许 SkateJs 会是 1 个不错的解决方案,基于 Web Components 规范来进行前端组件化。

我们最近正基于此在开发相应的前端框架——LuDesign,目前尚未完成 但可供参考。

https://github.com/kikyous/sprockets-vue

刚做的,把.vue 文件和 Asset Pipeline 结合起来,还在比较初级的阶段,不过已经用在公司的生产环境了

  • index.vue
<script lang="coffee">
{
  data: ->
    search: ''
    members: []
  methods:
    clear: ->
      this.search = ''
}
</script>

<template>
  <div class="container">
    <div class='search icon-input'>
      <span class="search-icon glyphicon glyphicon-search"></span>
      <input class="form-control" type="text" v-model='search'>
      <span @user1='clear' class="clear-icon glyphicon glyphicon-remove"></span>
    </div>
    <card v-for="m in members" :m='m'></card>
  </div>
</template>
  • application.coffee
#= require ./index

new Vue(
  el: '#search',
  components: {
    'index': VCompents['index']
  }
)

目前正在做 style 的支持

前后端分离是必要的,你做的项目可能对移动端,h5 端等同时并存的比较少,如果是管理后台或网站类的,肯定是直接上最快

#5 楼 @i5ting

  • "H5 端" 为什么必须要接口呢?
  • 移动端需要的接口,跟 admin, "网站", "H5 端" 需要的接口,往往差距很大

#2 楼 @small_fish__ 是说 react_on_rails 这个项目么?

确实不错,但是感觉它把事情搞得很复杂。尤其是服务端渲染,在服务端装一个 node.js, 提前运行 JavaScript 生成 HTML 片段......

#3 楼 @cn_boris 😍

而来自于 fullscreen.com 的 bh 则启迪了我们基于 Rails Helper 进行组件化的灵感。

我们之前也是这个思路,但是整理这些 helper 很花时间; 如果社区的风不往这个方向吹,这样做会很累。

现在前端轰轰烈烈的组件化,如果利用起来,应该能方便很多。

我也看好组件化,不过是原生实现。

Custom Elements v1: Reusable Web Components

https://developers.google.com/web/fundamentals/getting-started/primers/customelements

#8 楼 @42thcoder 是这样的。

我们一开始是想通过封装 Helper 来实现组件化,但后续发布开发成本其实挺高。所以之后用 SkateJS 进行了重写,文档首页的相关说明还没来的及修改....

SkateJS 中可以用 JSX 语法来写原生的 Web Components 组件,然后通过 polyfills 支持到 IE9+。目前的思路是用 SkateJS 来写细粒度的组件,用 Helper 来做大粒度组件/范式的封装。

例如:

/*doc
 ---
 title: Discussion 评论框
 name: discussion
 category: 组件
 ---
 A publisher is an advanced longform text input form element.
## 代码演示
 <lud-discussion name="replay-feed" placeholder="输入评论内容..."></lud-discussion>
 */
import './_index.scss';
import ludComponent from '../../lud_component';
import * as skate from 'skatejs';
class ludDiscussion extends ludComponent{
  static props = {
    name:  skate.prop.string({ attribute: true }),
    placeholder:  skate.prop.string({attribute: true }),
    child: skate.prop.string(),
    input_name: skate.prop.string()
  };

  static created(el) {
    el.input_name = el.name;
    $(el).attr('name',`${el.input_name}-wrap`).addClass('lud-discussion');
    el.child = el.innerHTML;
    el.innerHTML = null
  }

  static render(el){
    let $el= $(el);
    //noinspection CheckTagEmptyBody
    return(
      <textarea name={el.input_name} className="lud-textarea lud-text-longform lud-discussion__input"
                placeholder={el.placeholder} onFocus={()=>$el.addClass('lud-is-active')} ></textarea>
    );
  }

}
skate.define('lud-discussion',ludDiscussion);
# 伪代码,未经测试
def discussion(record, name='content')
      form_for path, class: 'lud-form' do
        content_tag :div, class: 'discussion--box' do |f|
          concat content_tag 'lud-discussion', record[name], name: "#{f.object_name}[name]"
          concat f.submit
        end
      end
end

那还不如用 jQuery, https://ruby-china.org/topics/31383, 我之前也跟你有一样的想法。如果不用 json 映射 data,vue 的效力不大。ujs 本身也是一个很好的组件化思路。

#9 楼 @Rei 期待它发展得更快~

#11 楼 @mingyuan0715

我的设想,一样可以用 JSON 映射 data~

用类似 gon 的思路,https://github.com/gazay/gon

#7 楼 @42thcoder react_on_rails 默认情况下服务器端渲染用的是 execJS,readme 里说了没必要用 node.js

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