咱们为何以及是如何从 Angular.js 迁移到 Vue.js?

在我写这篇文章的时候,咱们刚刚从咱们的应用程序代码库中删除了最后一行AngularJS代码,结束了一个为期4个月的非侵入性工做,将咱们的应用程序从AngularJS迁移到VueJS。在这篇文章中,我将分享咱们在整个过程当中的经验。javascript

一些背景介绍

咱们的应用程序(Holistics.io)是一个基于SQL的商业智能(BI)平台,使用Rails、Sidekiq、PostgreSQL和AngularJS编写。咱们的Rails应用程序始于2013年末,做为一个简单的应用程序其中使用了jQuery和AngularJS。咱们使用AngularJS主要特性/功能以下:html

  • 查看模型绑定(控制器,视图+模板引擎)前端

  • 依赖注入(服务,工厂,指令)vue

  • Angular第三方组件(uib-modal,ui-select,...)java

其他的都是内部的自定义JavaScript。ios

Tocy
Tocy
翻译于 2017/10/19 22:13
 顶
0
 
 

咱们在 Angular 中遇到的问题

随着咱们应用的升级,咱们在使用 AngularJS 的时候遇到了这样一些问题:git

  • 渲染性能:做为数据工具,因为AngularJs的特性,咱们不得不花大量的时间来呈现一张巨大的数据表。es6

  • Angular 的文档不太好:在这成为问题以前,其余都不算什么问题。咱们越深刻地使用 AngularJS,就越以为它的文档实在难以理解。github

  • 双向数据流使得逻辑处理起来至关困难,不论是写组件仍是写视图控制器都是如此。这多是AngularJS很差使用最重要的一个缘由。编程

考虑不一样的框架

在决定以前,咱们仔细看看各个选项:

Angular 2

咱们确实花了些时间来研究 Angular 2。对于咱们来讲,Angular 2 甚至比 Angular 1 还让人难以理解。它带来了太多新的变化(TypeScript),新的模板语法等,但咱们以为这并无真正解决咱们的核心问题。除此以外,从 V1 到 V2 的迁移之路在那时就一直让咱们以为困惑。

边城
边城
翻译于 2017/10/19 23:25
 顶
0
 
 

ReactJS

咱们仔细审视了 ReactJS。尽管咱们很是喜欢它的哲学和生态原理系统,但有一件事情让咱们吃惊:咱们找不到一条清晰、干净、渐进的迁移路径,来阻止咱们在3-4个月内支持新功能。

AngularJS 的使用基于 HTML 的模板系统,而 ReactJS 是用的 JSX。咱们不能找到办法在迁移的过程当中让两种技术很好的并存。

还有一个次要的主观缘由,我发现 JSX 比基于 HTML 的模板更加冗长。

EmberJS

EmberJS 不是一个 JS 库,而是一个 Web 应用框架,咱们必须用基于 EmberJS 重写全部东西。

边城
边城
翻译于 2017/10/20 00:06
 顶
0
 
 

咱们为何选择了 VueJS:逐步迁移

综合考虑各方面因素,咱们最终选择了 VueJS,但对于咱们来讲,最重要的决定性因素是:咱们看到了一个清晰、可逐步迁移到 VueJS,而又不会破坏发展路径的迁移路径。实际上,我敢打赌,在整个迁移期间,咱们的客户都没有注意到什么明显的变化,他们不会知道本身访问的页面中,哪些是 Angular 实现的,哪些是 VueJS 实现的。

Vue 采用了与 ReactJS 类似的技术,基于组件,属性下行事件上行等。它与 AngularJS 在模板引擎方面有着惊人的类似。它就像 AngularJS 和 ReactJS 的优美结合。这让咱们以为完美,由于咱们有大量的 AngularJS 模板,而咱们的主要问题是 Angular 组件带来的复杂逻辑。

边城
边城
翻译于 2017/10/20 00:16
 顶
2
 
 

实际上多数时候咱们须要作的只是将代码中的 ng- 改成 v-,简直太美妙了!

随着深刻,咱们愈加以为做出了正确的选择,它解决了咱们早期遇到的问题:很好的性能,单文件组件,清晰的代码结构,槽,等等。

并且,在迁移的过程当中,因为 Vue 结构的方式(单向数据流,基于组件),它迫使咱们反思和重构代码,而不是继续写烂代码,这简化了咱们的代码逻辑。

我还想说的最后一点,我发现 VueJS 的文档写得很是好,结构也很是清晰。这也是咱们选择 VueJS 的另外一个主要缘由。我第一次使用 Vue 的时候,花了 30 分钟来阅读它的文档,当即以为必需要试试这个东西。

边城
边城
翻译于 2017/10/20 00:25
 顶
0
 
 

咱们是怎么进行逐步迁移的:

下面是咱们迁移的简单步骤(注意有些内容与咱们运行的 Rails 应用环境有关,若是你没有使用 Rails,可能会有些不一样):

1. 把 AngularJS 控制器逻辑转换到 VueJS

在逐步迁移策略中,咱们要在引入 VueJS 时尽量少作改动。所以,咱们从标准的 AngularJS 和模板文件开始修改,将 VueJS 引入其中:

// user_edit_controller.js.es6` import Vue from 'vue' app.controller('UserEditCtrl', ['$scope', '$http', 'Ajax', 'Util', 'Modals',     function ($scope, $http, Ajax, Util, Modals) {     let vapp = new Vue({       el: '#v-wrapper',       components: {           ...       },       data: {       }     });   } ]);

 

<!-- `users/edit.html.erb` --> <div ng-controller="UserEditCtrl">     <div id="v-wrapper">     <!-- vuejs logic goes here... -->     <input v-model="username" placeholder="Username" />     ...   </div> </div>

 

咱们在应用中引入了 Vue 的逻辑,却不须要改变任何相关应用的前端结构。这极大程度的帮助咱们下降在迁移过程当中发生错误的风险,咱们能够花 1-2 个小时迅速地将一小部分 AngularJS 实现的东西转换为 VueJS 实现,而后测试并部署,不用担忧它会致使回归缺陷

边城
边城
翻译于 2017/10/20 00:34
 顶
1
 
 

2. 把 AngularJS 服务转换为 ES6 模块

咱们首先须要找到一个 AngularJS 中大量使用的 $http 服务的替代品。咱们直接使用了 axios。咱们再也不直接使用 $http,但咱们围绕它进行了抽象封装,以使修改变得很是简单。

而后,咱们像这样定义了大量的 AngularJS:

// users.js app.service('Users', ['$http', 'Ajax',     function ($http, Ajax) {     this.create = function(user) {       // ...     }   } ]);

 

使用 ES6 类语法代替就好:

// users.js.es6 export default class Users {     static create(user) {     // ...   } }

 

若是其它控制器中使用有 Angular 代码在使用这些服务,咱们会复制这些服务并使用 ES6 类语法来实现,同时保持原有的 Angular 版本,直到再也不有 Angular 代码使用它们为止。这会在短期内让代码出现重复,但咱们只须要当心一点,在代码中多写些注释来关联两个版本。

边城
边城
翻译于 2017/10/20 00:43
 顶
0
 
 

3. 使用 VueJS 组件代替 AngularJS 控制器

完成上述两点以后,一些 AngularJS 控制器能够彻底迁移到 VueJS,这和上面的第 2 步类似,咱们使用 ES6 语法来代替 app.controller() 定义。不过此次,咱们使用 Vue 的单文件组件:

文件:user_edit.vue

<template>     <div>     <!-- vuejs logic goes here... -->     <input v-model="username" placeholder="Username" />     ...   </div> </template> <script>   import Users from 'users.js.es6'   export default {     data: {       },   methods: {      },   mounted() {     // initializing   } }; </script>

 

4. 为 Rails 控制器/视图添加安装入口

默认状况下,每一个 Rails 页面加载的时候会渲染视图。在上面的 Vue 单文件组件中,咱们将 Raisl 视图,users/edit.html.erb 文件,改成:

<div class="v-user-edit">     <user-edit></user-edit> </div>

 

而后加些代码在页面加载的时候将其安装为正确的 Vue 组件:

import UserEdit from 'user_edit.vue'   let vueConfig = {     el: '.v-user-edit',   components: {     UserEdit   } }; new Vue(vueConfig);

 

实际上,上面的代码被抽象成了可复用的函数,在不一样的页面中调用。

边城
边城
翻译于 2017/10/20 00:49
 顶
1
 
 

总结

咱们在 2017 年九月末完成了框架的迁移,经历了大约 4 个月时间的非侵入性(咱们在迁移过程当中会继续添加其它新特性)工做。实际上咱们并无把迁移做为最紧急的任务,无论何时,只要咱们的改动涉及到旧的 Angular 代码,咱们会先把它转换成 Vue 实现,而后再进行变动。

迁移完成后,咱们收获了:

  • 很是整洁的代码和模块(基于组件的),以及 VueX 和 Vue Store;它们大大提升了编程效率

  • 再没有复杂的逻辑

  • 改善了 UI 性能

这并非说 Vue 就是最好的,它只是在咱们特定的状况下工做良好:Angular 固有的设计本质致使使用 Angular 实现应用很重,而 Vue 为咱们很好地填补了这一空白,这一切都是天然而然地逐步迁移实现的。

你怎么想?请在下面的评论中与咱们分享。但愿了解更多大家遇到的状况!

相关文章
相关标签/搜索