I spent a few days on and off learning parts of Vue to write a small app. I wrote the same app with Angular. I'm sharing my experience of working through Vue for the first time to help others that may be curious about the JavaScript framework landscape.

This post explores the code for both the Angular and Vue apps. Spoiler: you'll find that the code and concepts are very similar. :) I had a lot of fun working through Vue with Sarah Drasner. Pair programming or simply just talking to friends about code is a great way to learn and share ideas.

We all benefit when we learn to enjoy and embrace the similarities and the differences that help push the Web forward.

Both apps are very small. Both apps are not indicative of how we may refactor to expand to build a large scale app. In fact, the tldr; is that both apps in Angular and Vue have a lot in common.

Here are the posts in this series, if you want to catch up or jump around:

index.html

Let's begin with the file that starts it all: index.html. Notice that both of these are very similar and very short. Each uses WebPack for a build process and thus defers to WebPack to crank things up.

On the left, Angular adds a few extra things. Here we see a <base> tag which is useful once we add routing. We haven't added routing yet, so the <base> tag is uncesessary at this moment. Angular also adds the viewport and a favicon. None of this is a big deal.

The <body> is where we find Angular hosting the root component app-root and Vue hosting a <div> where the root component will be associated. Again, fairly similar.

The Vue code adds in a build.js script, and at first glance, it seems the Angular one does not. Angular adds the startup scripts in the built version of the app. In other words, when we build the Angular app, the index.html will contain these scripts too.

Thus the index.html files are fairly similar, and it's kinda cool how small they are.

main.js

Both apps kick their code off from a main.js file. Wait, the Angular app uses TypeScript, so isn't it a main.ts file? Yeah - but - TypeScript compiles to JavaScript, and it becomes - you guessed it - main.js.

Both apps import from their frameworks, respectively. Both apps then import the root file for their frameworks. Angular imports the AppModule while Vue imports the root App component. Angular then has a quick check to disable some features when it is running a production build vs. a development build which is helpful for turning off debug capabilities.

The syntax to kick things off and launch the starting root component then follows. Angular bootstraps the AppModule while Vue associates the App component with the HTML element with the id app that we saw in index.html.

Notice that the Vue app also declares the component App. We'll come back to this in the next section.

Different syntax, different frameworks, but again, pretty simple stuff to kick things off from both.

app.module

This is one of the more apparent differences between Angular and Vue: Angular apps contain a manifest of the leading players in an app while Vue doesn't have this concept. The file app.module.ts contains AppModule which defines a class decorated with the @NgModule() decorator.

In this Angular app, the app.module.ts file declares the components used by the app, imports Angular features (e.g., browser, forms, and HTTP), declares the services and defines which component should kick things off. Remember I mentioned how the Vue app declared one of its components in the main.js? It's not the same exact thing, but we can see here that the Angular app has a similar declaration. Except with Angular, the file app,module.ts declares all of the components in this small app.

The Vue app kicks off the root component App in it's main.js, while the Angular app kicks off its root component AppComponent in app.module. Different patterns, but very once again, easily digestible patterns to follow in both cases.

App Component

Each app has a root component. The Angular one uses a convention to name its components with a suffix of Component. So Angular has AppComponent while Vue has App. Both have similar templates. Vue's App component has an id in the div and both frameworks list their child components' selectors differently with app-hero-list and HeroList, for Angular and Vue respectively. Both apps also contain some root styling.

The Angular app has a small class with one model property for title. The Vue component defines one model property for title, too. The Vue App component declares it's child component, HeroList here, directly in the component that uses it. The Angular app declares these back in the manifest in the app.module.ts file.

One difference that stands out is that the Angular app uses a *.ts file while Vue uses a *.vue file. As long as the editor and tooling know how to display them, let us edit them, give us tooling, and build them, I don't think it matters much what the extension is.

Once again, we see how easy it is to observe the similarities.

Hero List Component

Each app has a component for displaying the heroes to the user, from where they can select a hero to see his/her details. Both are using inline templates, which define the HTML for the compoennts.

The Angular component, hero-list.component.ts, imports from its framework, then it imports a model for the Hero class, then imports a HeroService. The Vue app imports a hero service (down on line 31) and then it imports its child component, from HeroDetail.vue. They both import a service, but the other files differ. These are minor differences, though.

Angular already declared its HeroDetailComponent component in app.module. The Angular app uses a declared Hero model class. The Vue app could certainly use a model, but there was no need to do so here.

Here comes the coolest part of the similarities: the templates are extremely similar to each other. Take a moment to look at the HTML templates side by side. They both have the same number of lines and very similar syntax. The Angular app defines the template in a string while the Vue app establishes the template inside of a <template> tag.

The binding syntax is quite interesting too. We'll explore the syntax for template bindings in more the next post in this series.

The bindings for Angular and Vue are indeed interesting. In Angular, we have a (click) binding syntax while in Vue we use @click. Here are some other similarities in the bindings, in the following table.

binding Angular Vue
click event (click) @click
enter key-up event (keyup.enter) @keyup.enter
add/remove content *ngIf v-if
model binding [(ngModel)] v-model
HTML element reference # ref

Wait! What about the code? Once again, very very similar code.

The Angular app defines a TypeScript class with properties that define the hero list's model. The Vue app establishes the model in a data property. These are the same three model properties.

The Angular app uses dependency injection to get a reference to the hero service, while the Vue app imports its similar service. Different styles, but it is easy for us to make the transition in either direction here.

Both apps have the same set of methods. Angular uses RxJS by convention to communicate with HTTP while Vue uses Axios with promises by convention. That's why we see subscribe for Angular and then for Vue in the calls to the service, for the asynchronous operations. These are just different techniques, and the code is very similar in this side by side example.

Both of these components also have scoped styling using SASS. Scope styling is kinda cool since the styles will only apply to the components. This makes it easy to identify which styles will apply to the component and perhaps, more importantly, this makes it easy to ensure that styles only apply where we intend.

Hero Detail Component

Both hero detail components are also very similar. The Angular file hero-detail.component.ts starts by importing the features (referencing them). Then they both define their respective templates. Angular tends to explicitly define the features they use, which is why we see more imports at the top of the file.

The templates are similar other than binding syntax, just like the hero list components' templates.

The code for these components is quite interesting. The Angular HeroDetailComponent uses the @Input() decorator to identify that the hero model property can be passed in (via a binding) from the parent component. The Vue HeroDetail component uses the props property to identify its hero model property can be passed in from its parent component. We get the same result, with different techniques.

Each component defines two model properties for addingHero and editingHero. Angular does this with class properties while Vue does it as members of the data property.

Both apps set focus to elements once they are rendered and ready on the Web page. However, the way they get to those elements is interesting. The Angular app grabs references to the two elements using the @ViewChild() decorators while the Vue app uses an inline reference in the template combined with this.$refs in its code to reference its elements. The Angular the app handles the focus in the life cycle event ngAfterViewInit while the Vue app is handling setting the focus in the mounted event.

Take a close look at the @Output() decorators in the Angular app and we'll see that these help us emit events from the HeroDetailComponent to its parent component. Notice that for Angular, the event emits on line 64 in the clear method. The Vue app also emits events. Vue uses the this.$emit function to do the same thing (see line 56 in Vue's HeroDetail component). Obviously Angular and Vue have different syntax for some things.

In and Out of Components Angular Vue
input property @Input() props
emit an event @Output() with EventEmitter this.$emit

Overall, the components are once again very similar and it is easy to see how once you know one of these frameworks, it can be easy to use the other.

Summary

Where does this leave us? Good question. The takeaway for me is that I found it quite easy to straddle the line between Vue and Angular. I can take an Angular app and see fairly quickly how to translate the way I do things in Angular and how Vue might do them.

The intent here is to show two interesting ways to solve a problem - to build apps for the modern web. Both Angular and Vue share some interesting concepts. Both are paying close attention to how the Web is evolving, and they are evolving with it.

We all benefit when there are multiple great options, especially when we look at them in a friendly, welcoming, and open-minded way. Both Angular and Vue are popular (along with some others like React). All of these are great solutions.

I'll repeat this because it's important ...

We all benefit when we learn to enjoy and embrace the similarities and the differences that help push the Web forward.

Source Code

You can find the source code for these apps here: