Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从 MVVM,vue2.0 的过滤器之争看 js 数据格式化 #2

Open
leopen-hu opened this issue Dec 4, 2016 · 4 comments
Open

从 MVVM,vue2.0 的过滤器之争看 js 数据格式化 #2

leopen-hu opened this issue Dec 4, 2016 · 4 comments

Comments

@leopen-hu
Copy link
Owner

从 MVVM,vue2.0 的过滤器之争看 js 数据格式化

基本说明

  • 我没有使用过 vue2.0,只是看了他们对于 vue2.0 中 filter 是否应该被放弃的讨论
  • 我个人支持抛弃过滤器,我使用过 angular1.x 的 filter (下文不特指都是 template 中的 filter),但是这给我造成困扰,特别是越来越多的逻辑出现在 template 中的时候
  • 写这篇文章的本因是我对于数据格式化应当在 vm 还是在 view 中产生了困扰,这个格式化在 template 中可以看成是 render,在 js 中是 format,这个问题目前还是没有确切的答案

主要内容

  • 项目中的困扰
    我们公司的项目在使用 angular1.x,使用上 angular 之初,我觉得 filter 十分好用,数据格式化只需要在 template 中使用管道操作符|,而不需要为此写大段的 js 函数。但是随着开发的深入,我越来越感觉到困扰,因为我过量使用了 filter。例如,后端接口的返回的数据部分格式化了,部分没有,导致数据的格式化是一个比较重要的工作,甚至我为此研究了异步 filter。
    这次在开发一个新的页面时,我需要对大量的数据进行格式化(包括汉化),包括时间,姓名,订单状态等,存在的两种解决方法让我有些不知所措。

    • 使用 js 需要在代码中对列表数据进行循环,而这一步骤在 view 渲染中使用 ng-repeat 也会再循环一遍。
    • 使用 template 中的 filter 会让我在代码中对于数据的判断有时是英文,有时是中文,逻辑十分不统一,经常写错,然后必须去看接口定义甚至后台实际返回的数据。
  • 了解 MVC,MVVM
    由于拿不定主义,于是我决定去找一找最佳实践,其中一个方向就是 MVVM 中对于各个模块的功能划分究竟是怎样的。谈到 MVVM,自然不能忽略 MVC。简单介绍如下:

    • MVC:
      • model:模型,数据保存;改变后告诉 view,给予反馈。
      • view:视图,用户界面;渲染 model,传送指令给 controller。
      • controller:控制器,业务逻辑;接受view指令,执行逻辑,要求 model 改变。
    • MVVM:
      • model:模型,数据保存;改变后告诉 view model(后简称 vm)。
      • view:视图,用户界面;与 vm 双向绑定,渲染 vm 的数据,调用 vm 的方法。
      • view model:视图模型业务逻辑;定义界面数据模型,定义数据的操作方法,要求model改变。

    MVVM 较之 MVC 最大的改变就是 vm 取代 controller,vm 与 view 双向绑定,这样 vm 一般都是针对一个 view 的,但同时也是松耦合的。
    实际上更多的时候 vm 和 controller 是同时存在的(MVCVM),一般由 vm 定义数据和方法,controller负责路由,监听 view 的事件,调用 vm 方法,对 vm 的返回作出响应,告诉 view 渲染的 vm 数据等。

  • 数据格式化
    回答问题,数据格式化应当在哪里?在 vm 中似乎很合理,应为 vm 中就可以定义方法,那么定义一些格式化的方法当然可以。但在 template 中似乎也没有什么不可以,对于数据的渲染同样可以有不同的渲染方式。于是我继续带着疑问搜索,这次我把目标放在 angular 的 filter 最佳实践上,但是没有什么问题比较切合我的疑问,带着尝试的心态搜了下‘前端数据格式化应该在 vm 还是 view,结果又搜出来一篇文章《MVVM 模式》,里面认为格式化还是应当在 vm 中实现,并引导我去看了 vue2.0 的争论。

  • vue2.0取消filters的争论
    搜出来一个vue2.0取消filter的争论,粗略的看了一遍,大家对于这个的观点很有不同,最后开发者还是做出了一些妥协:

    • 开发组:我们要保持 js 的纯度,最好等 js 自己的管道操作符出来我们再考虑
    • 开发者A:filters 的写法如此优雅,怎么可以抛弃,而且我可以使用管道在 template 中写一堆连续操作,js 中写起来麻烦死了
    • 开发者C:不仅仅要考虑 js 开发者,不会 js 的也可以拿 vue 当模板系统使用啊,大部分模板都有过滤器
    • 开发者D:过多的 filters 在 template,导致逻辑分散各处,不应当支持,想要格式化,应当自己写函数,去学 js 吧
    • 开发者E:额,虽然我也支持纯函数,但是 filter 真的好用啊,等语言的管道操作不知道什么时候啊,要不我们做成可以选择的包来支持一下,等语言特性出来再搞新的嘛
    • 尤大大:别吵了,我们做出了以下决定:

      Here's the final decision:
      Filters will be supported, but only inside text interpolations. This limits them to text formatting purposes while enforcing other logic into JavaScript land.
      Vue 2.0 will ship with no built-in filters. The community can create their own filter packs if needed.
      The filter syntax will change to use function invocation syntax for arguments instead of space-delimitered. This brings it more inline with JavaScript and other popular templating languages (Jinja2, swig, twig...):
      {{ date | formatDate('YY-MM-DD') }}

结论

一圈转下来,似乎也没有个什么结论,从模式上看二者似乎都可以(虽然我个人更倾向vm),从最新的社区讨论上看,也是二者都有拥趸(dun,三声,就知道你们不会读)。那么我们究竟该怎么做了?个人有一点不成熟的看法。

  • 两种方法都是可以接受的,尽量使用 js 函数,在 template 中使用 filter 是可以接受的,但是应当遵循以下几点:
    • 应当只是字面变量的格式化。例如日期格式化;
    • 不应当包括逻辑,例如由code转name;

参考及引用:

@leopen-hu
Copy link
Owner Author

issue: 数据在界面上绑定中文,但对数据操作发回后台需要使用英文的情况下,似乎template中处理会更easy,这个应该如何权衡?

@leopen-hu
Copy link
Owner Author

@leopen-hu 这个似乎并不会成为一个问题,对于枚举型的数据来说,同时绑定value和label是合适的解决方法。对于可以自定义的数据,例如input[text],基本不应该存在这种情况,因为提交的数据应当就是你填写的数据,况且这种情况在template中更不容易处理。

@leopen-hu
Copy link
Owner Author

leopen-hu commented Dec 20, 2017

接触得越多就越了解一些东西,事实上,有很多数据的转换是不适合在数据层面做的,比如表格内容的显示,因为实际数据常常用一些code,而显示应当用name,那么就会经常出现在view层做转化的需求,因为涉及到编辑等操作的时候,绑定的数据必须是code。

@leopen-hu leopen-hu reopened this Dec 20, 2017
@leopen-hu
Copy link
Owner Author

最近使用iview,我们使用的就是render函数,绑定一个数据,然后根据该数据渲染出其他数据

@leopen-hu leopen-hu reopened this Dec 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant