How to Migrate from AngularJS to Vue

…using ngVue

Nicolas Payot
DailyJS
5 min readMay 23, 2017

--

Our front-end application at Dawex (a marketplace for monetizing and acquiring data) is a single-page app powered with AngularJS. The first lines of code were written during the summer of 2015. Back then, it totally made sense to choose this framework. The team had lots of experience with it and it fairly matched our needs for the platform. Angular (the new one) was only in alpha version. React had just started to become popular, used primarily among the front-end community, but we didn’t have enough experience with it. And Vue… well, it hadn’t yet made it.

Who knew Vue would end up with the big players?

Even though our app is developed with an old framework (it saddens me to write that but, hey… 2009), we built a solid architecture and it scales pretty damn well!

From the very beginning, we always tried to stay on top and do what’s best for the platform and our users. Neither was the developer experience forgotten.

We’re using a full component-based design with modern JavaScript (ES2015+) and advanced tooling such as Babel, ESLint, Gulp, Jest, Redux, Webpack, and other great technologies that the JavaScript open-source scene has to offer.

Then, what?

As a front-end developer, I get excited every time a new shiny framework / or tool (you name it) pops up in my Twitter feed (of course, this doesn’t mean it’ll land right away in our stack). As you can guess, Vue piqued my interest — so much so that I thoroughly wanted to start to migrate our application from AngularJS over to Vue.

The Vue API is much simpler. It’s pretty impressive how fast it is to get on track with it.

For instance, you only need a single file (.vue) to create a component, and there you go — ready to use! Sometimes, I still get confused with the camelCase/kebab-case specification between declarations and use in HTML templates with AngularJS.

We don’t really suffer from performance problems, but let’s be honest: dirty checking is just NAY. Reactivity system within Vue is unobtrusive and combined with its lightweight virtual-DOM implementation, it allows change detection to be lightning fast.

Also, the developer experience is way better. I find myself much more satisfied and enthusiastic when developing with Vue. I won’t go any further with Vue vs AngularJS, there are plenty of other blog posts about it.

Back to the migration topic. It can’t be done in one shot. It should be progressive and as smooth as possible.

The next part of this article details some thoughts I had about this challenge:

Meet ngVue

ngVue is an AngularJS module. It allows you to painlessly integrate Vue components within an AngularJS application.

What this means is that we could start any new development feature with Vue or convert an existing one.

Here are slides about it from a talk I gave at LyonJS meetup: http://slides.com/npayot/ng-vue.

This module offers a directive: vue-component, and a factory: createVueComponent.

The directive gives the possibility of embedding a Vue component with its defined properties. The factory will yield to the same result as it creates a reusable directive that is bound to a specific Vue component.

vue-component

As an example, let’s say we have a simple Vue component that we’d like to add within an AngularJS one:

Here’s the AngularJS component:

As you can see here, the vue-component directive takes two attributes: name and vprops.

name should be the Vue component name registered as a value in an AngularJS module. vue-component needs it so that it can get, in its link function, the Vue component instance through the $injector service. This way, it can be instantiated and rendered on the <vue-component> tag. Also, ngVue module needs to be added to the AngularJS main module.

vprops allows you to pass data from an AngularJS context to the Vue component. It can also be used this way, giving you a finer control to your component properties:

createVueComponent

This factory is interesting because it enables the binding of a Vue component to a custom directive. Thus, using vue-component is not necessary, neither registering the Vue component as a value, and your own custom tag can be used.

Integration of Vue components is a first step in the migration path.

Unfortunately (in this particular case…), AngularJS comes with a thick layer we can’t use within Vue: Dependency Injection. If you’re developing and maintaining an AngularJS app for years, I bet you’ve created a bunch of sweet services / factories / providers. This would be a shame not being able to use them within Vue components, wouldn’t it? At least during the cohabitation of AngularJS and Vue. Well, there might be a solution… Let’s explore it!

Using AngularJS services within Vue components

Thanks to ES2015 modules, AngularJS services instances can be exposed and then imported. No dependency injection! To enable this mechanism, services instances have to bet fetched in AngularJS context. $injector to the rescue! Here is how it works:

Then, we can simply import and use helloService instance anywhere: import { helloService } from 'path/to/hello.service;

TADA! 🎉🎉🎉

Conclusion

I think ngVue and getting rid of dependency injection for AngularJS services (well, sort of…) represent a good approach to progressively migrate to Vue.

Obviously, there are other limits and challenges to be met that will eventually be the subject of another blog post when we start. 🙂

--

--

Nicolas Payot
DailyJS
Writer for

Senior Frontend Developer at Malt / JS & UI enthusiastic