当前位置: 首页 > 科技观察

我们为什么以及如何从Angular.js迁移到Vue.js?

时间:2023-03-17 12:18:17 科技观察

在我写这篇文章时,我们刚刚从我们的应用程序代码库中删除了最后一行AngularJS代码,结束了为期4个月的非侵入式努力,将我们的应用程序从AngularJS迁移到VueJS。在这篇文章中,我将分享我们在整个过程中的经验。一些背景我们的应用程序(Holistics.io)是一个基于SQL的商业智能(BI)平台,使用Rails、Sidekiq、PostgreSQL和AngularJS编写。我们的Rails应用程序始于2013年底,是一个使用jQuery和AngularJS的简单应用程序。我们使用AngularJS的主要特性/功能如下:视图模型绑定(控制器、视图+模板引擎)依赖注入(服务、工厂、指令)Angular第三方组件(uib-modal、ui-select,...)其余的都是内部自定义的javascript。我们在Angular中遇到的问题随着我们应用的升级,我们在使用AngularJS时遇到了一些问题:渲染性能:作为一个数据工具,由于AngularJS的特性,我们不得不花费大量的时间来渲染一个Huge数据表。Angular的文档不是很好:在这成为问题之前,其他都不是问题。我们越是使用AngularJS,就越难理解它的文档。双向数据流让逻辑变得相当困难,无论是写组件还是写视图控制器。这可能是AngularJS不好用的最重要原因。考虑不同的框架在决定之前,让我们仔细看看选项:Angular2我们确实花了一些时间研究Angular2。对我们来说,Angular2甚至比Angular1更令人困惑。它带来了太多的新变化(TypeScript),新的模板语法等等,但我们觉得并没有真正解决我们的核心问题。除此之外,从V1到V2的迁移路径当时让我们感到困惑。ReactJS我们仔细研究了ReactJS。尽管我们喜欢它的哲学和原则生态系统,但有一件事让我们感到惊讶:我们找不到一条清晰、干净、渐进的迁移路径来阻止我们在3-4个月内支持新功能。AngularJS使用基于HTML的模板系统,而??ReactJS使用JSX。在迁移过程中,我们找不到让这两种技术很好共存的方法。还有一个不太主观的原因,我发现JSX比基于HTML的模板更冗长。EmberJSEmberJS不是一个JS库,而是一个Web应用程序框架,我们必须基于EmberJS重写所有内容。为什么我们选择VueJS:一步一步的迁移经过所有考虑我们最终选择了VueJS,但对我们来说最重要的决定因素是:我们看到了一个干净的、一步一步的迁移到VueJS而没有中断开发路径到迁移路径。事实上,我敢打赌,在整个迁移期间,我们的客户并没有注意到明显的变化,他们也不知道他们正在访问的页面哪些是用Angular实现的,哪些是用VueJS实现的。Vue采用了类似ReactJS的技术,基于组件,属性下行事件上行等,在模板引擎方面与AngularJS惊人的相似。它就像是AngularJS和ReactJS的完美结合。这对我们来说非常有效,因为我们有很多AngularJS模板,而我们的主要问题是Angular组件带来的复杂逻辑。其实很多时候我们只需要将代码中的ng-改成v-就好了!随着深入,我们越来越觉得自己的选择是正确的,它解决了我们之前遇到的问题:非常好的性能,单文件组件,清晰的代码结构,slots等等。另外,在迁移过程中,由于Vue的结构化方式(单向数据流,基于组件),它迫使我们反思和重构我们的代码,而不是继续编写糟糕的代码,这简化了我们的代码逻辑。最后一件事我想说的是,我发现VueJS的文档写得非常好并且结构非常清晰。这也是我们选择VueJS的另一个主要原因。第一次使用Vue时,我花了30分钟阅读了它的文档,并立即觉得我必须尝试一下这个东西。我们是如何一步步迁移的:以下是我们迁移的简单步骤(注意部分内容与我们运行的Rails应用环境有关,如果你没有使用Rails,可能会有所不同):1.转换AngularJS控制器逻辑以VueJS的渐进迁移策略,我们希望以尽可能少的更改引入VueJS。因此,我们从标准的AngularJS和模板文件入手,将VueJS引入其中://user_edit_controller.js.es6`importVuefrom'vue'app.controller('UserEditCtrl',['$scope','$http','Ajax','Util','Modals',function($scope,$http,Ajax,Util,Modals){letvapp=newVue({el:'#v-wrapper',组件:{...},数据:{}});}]);...

]);我们在应用程序中引入了Vue的逻辑,没有改变任何相关的应用程序前端结构。这极大地帮助我们降低了迁移过程中出错的风险。我们可以花1-2小时快速将一小部分AngularJS实现转化为VueJS实现,然后测试部署,不用担心会造成回归缺陷。2.将AngularJS服务转换为ES6模块我们首先需要找到AngularJS中大量使用的$http服务的替代品。我们直接使用了axios。我们不再直接使用$http,而是对其进行了抽象,使修改变得非常简单。然后,我们像这样定义一堆AngularJS://users.jsapp.service('Users',['$http','Ajax',function($http,Ajax){this.create=function(user){//...}}]);]);使用ES6类语法代替://users.js.es6exportdefaultclassUsers{staticcreate(user){//...}}]);如果在其他控制器中有使用这些服务的Angular代码,我们将复制这些服务并使用ES6类语法实现它们,同时保持原始Angular版本,直到Angular代码不再使用它们。这会在短时间内重复代码,但我们只需要小心并在代码中写更多注释以链接两个版本。3.使用VueJS组件而不是AngularJS控制器。完成以上两点后,AngularJS的一些控制器就可以完全迁移到VueJS了。这类似于上面的步骤2。我们使用ES6语法来替换app.controller()定义。但是这次,我们使用Vue的单文件组件:file:user_edit.vue]);4.为Railscontroller/view添加安装入口默认情况下,每个Rails页面在加载时都会呈现一个视图。在上面的Vue单文件组件中,我们将Raisl视图users/edit.html.erb文件更改为:]);然后添加一些代码以在页面加载时将其安装为正确的Vue组件:importUserEditfrom'user_edit.vue'letvueConfig={el:'.v-user-edit',components:{UserEdit}};newVue(vueConfig);]);其实就是把上面的代码抽象成一个可重用的函数,在不同的页面中调用。总结我们在2017年9月底完成了框架的迁移,大约用了4个月的非侵入式工作(我们会在迁移过程中继续添加其他新特性)。我们实际上并不认为迁移是最紧迫的任务,每当我们的更改涉及旧的Angular代码时,我们都会先将其转换为Vue实现,然后再进行更改。迁移完成后,我们获得了:非常干净的代码和模块(基于组件),以及VueX和VueStore;它们极大地提高了编程效率,并且没有复杂的逻辑提高了UI性能这并不是说Vue是最好的,它只是在我们的特定案例中效果很好:Angular固有的设计性质使得使用Angular实现应用程序很繁重,而Vue填补了这个差距对我们来说很好,而且是一个自然的渐进迁移。