Originally published at Codegram's blog
Everybody seems to be switching to Vue lately. There are tons of articles about migrating from React/Angular to Vue. Me? I’m doing quite the opposite. After working with Vue for about 2 years, switching to Angular is an interesting process.
I started working with Vue in late 2016, right when version 2.0 came out, and I’ve been using it as my frontend framework of choice almost exclusively. Before that, I had little experience with coding, just a bit of AngularJS, jQuery and vanilla JS. At the time there were not many resources to learn Vue, so I basically learned by reading the documentation. It was a really nice experience. Happy times.
A few months ago I started working at Codegram, where the front end framework of choice is Angular. I thought, hey, I have experience now, how hard can it be?
The learning curve
Even if you’ve had years of experience working as a front-end developer, it is likely that you’ve only worked with HTML, JavaScript, and CSS. You might be familiar with the module system, and maybe you’ve used some build tools, like Gulp or Webpack.
When you start working with Vue, you can use just what you already know: HTML, JavaScript, and CSS. You could use Pug, TypeScript, and Stylus if you prefer any of those, but by default, you don’t need to learn anything else. Knowledge of Webpack helps, but the default configuration will work for most of the time.
Angular, on the other hand, imposes many things on you. In addition to the framework itself, that has a lot of concepts like modules, services, and so on, you also need to learn a new language (TypeScript) and RxJS.
True, TypeScript is more of a superset than an entirely new language, and if you are not working with a strict mode the type checking is mostly optional, but if you want to follow best practices, it adds quite a lot of overhead and slows down development a lot. I feel that a feature that with Vue I implemented in a breeze, with Angular takes much longer.
RxJS
RxJS is embedded in the way Angular works, so you need to follow a reactive programming pattern. I’ve come to really like RxJS, but I’ve had (and still have) a lot of trouble thinking reactive. It sure pays off, but imposing this on your framework can be a considerable stopper for people who don’t have experience with reactive programming. Also, sometimes these little graphs don’t help much:
With Vue, usually, the component will automatically react to state changes without us having to worry about it. The component will be re-rendered, computed properties will be recalculated if needed, and so on. However, there are certain things that will require a manual trigger. Let’s say we need to execute some method every time a route parameter changes. With Vue we need to set a watcher like this:
watch: {
'$route.params': function (params) {
// do the thing
}
}
With Angular and RxJS, route params is an observable so you can react to changes by tapping into the stream (or mapping, or any of the very cool RxJS operators)
this.route.params.pipe(
tap(params => {
// do the thing
})
);
I like Angular’s reactive approach better, but I can understand that imposing RxJS is not a choice Vue should make for you. There is an official RxJS integration, which is something I’m looking forward to trying.
The template system
It surprised me that, even though Angular and Vue both use the same approach when working with templates (no JSX, just good old HTML with a few bindings and directives), the experience ends up being really different.
So, the things I needed to learn to work with Vue templates were just v-for
, v-if
(and v-else
), v-bind:attribute
(or the shorthand :attribute
), v-on:event
(or the shorthand @event
). Basically, you need to append v-
to whatever you want to do and it will work.
The things I’ve had to learn to work with Angular templates: *ngFor
, *ngIf
, [attribute]
, (event)
, some certain attributes work with [attr.whatever]
, there is also the [(banana-in-the-box)]
for two-way binding (I must admit I love the name of that one, probably my favorite part about Angular so far). There is also [ngClass]
and [ngStyle]
, which I know they are different from [class]
or [style]
but I can never seem to remember how or why.
Also, if you want to do an if/else structure, you need to add an extra ng-template
and do something like:
<button *ngIf="someCondition; else otherBtn">
An action
</button>
<ng-template #otherBtn>
<button>
Another action
</button>
</ng-template>
And if you wanted to display a few items in each case without a wrapping element, you would need to first set the condition in a ng-container
and then create two different ng-template
. The condition is completely separated from the templates, making it much harder to read:
<ng-container
*ngIf="someCondition; then templateA; else templateA">
</ng-container>
<ng-template #templateA>
<p>Some text</p>
<button>An action</button>
</ng-template>
<ng-template #templateA>
<p>Some other text</p>
<button>A different action</button>
</ng-template>
In Vue I find it way cleaner and easier to understand:
<button v-if="someCondition">
An action
</button>
<button v-else>
Another action
</button>
And if you don't want a wrapping element, just use the v-if
in the template
:
<template v-if="someCondition">
<p>Some text</p>
<button>An action</button>
<template v-else>
<p>Some other text</p>
<button>A different action</button>
</template>
I’m sure there is a reason why Angular works this way, and I’m not trying to suggest that it’s a bad framework, but when you’ve experienced Vue’s simple approach, even minor things like that can become a big pain point.
The general opinion, which I can share, is that Angular shines when working on huge projects and big teams. Angular already makes many decisions for you so the team can focus on what’s important. However, that’s something you can get with any other framework as well. Use TypeScript with Vue or React. Follow a style guide and folder structure (Vue ESLint and Nuxt can help you with that). Follow best practices. You can create a terrible project that doesn’t scale with Angular, just as you can with React or Vue. A framework won’t push you into bad patterns nor will save you from mistakes.
Vue is usually praised for creating a great dev experience, but in the end, the best framework is the one you are most comfortable with. I’m going to leave you with this slide by Evan Schultz, which accurately represents how I feel about Vue: