Tutorial hero
Lesson icon

Learning Vue for Ionic/Angular Developers – Part 1

Originally published October 19, 2017 Time 14 mins

Learning Vue for Ionic/Angular Developers – Part 1: Vue Syntax vs Angular Syntax (this tutorial)
Learning Vue for Ionic/Angular Developers – Part 2: Navigation
Learning Vue for Ionic/Angular Developers – Part 3: Services/Providers and HTTP Requests
Learning Vue for Ionic/Angular Developers – Part 4: Storing Data with Local Storage, IndexedDB, WebSQL, and SQLite
Learning Vue for Ionic/Angular Developers – Part 5: Building with Cordova and the Vue CLI

The introduction of Stencil and the switch to web components means that you will soon be able to use Ionic with any framework you like. Previously, we have been limited to building Ionic applications with the Angular framework. I don’t use the term “limited” in any kind of negative sense, Angular is a great framework for building mobile applications, and I suspect it will remain the defacto framework for building with Ionic in the future.

But… we have options now! One of those options is, of course, the popular Vue framework. Why might you want to use Vue instead of Angular to build Ionic applications? I’m not going to get into that now, but in general, I would say: if you like using Vue more than Angular.

The Vue team have published a guide that compares Vue to other frameworks, and it seems to be a reasonably fair assessment. The key point of difference between Angular and Vue seems to be that Angular is more structured and opinionated, whereas Vue is more flexible and lightweight. Angular provides almost everything you need out of the box and it’s hard to deviate from that, Vue requires that you fill in some of the blanks yourself but gives you more room to decide.

It is also worth noting that building Ionic applications with Vue right now is going to be harder than with Angular. We are still in the very early days of the transition to web components, whereas Ionic/Angular has been stable for a long time now.

NOTE: The fact that I am writing this series does not mean that I am “switching” to Vue. I will continue posting more Angular/Ionic tutorials in the future.

Learning Ionic/Vue

Previously, when it came to learning Ionic it wasn’t (and still isn’t) all that important to differentiate between Ionic and Angular. If you were new to both frameworks you might just have “learned Ionic”, and picked up whatever Angular knowledge you needed along the way. When building mobile applications with Ionic, you’re really just mostly building Angular applications with a little Ionic “flavour”.

However, Ionic did change some key things about Angular – most notably the routing. Ionic ditched Angular’s routing in favour of their own mobile-centric push/pop style navigation stack. For this reason, if you were to just learn how to build applications with Angular, you couldn’t transition directly into building mobile applications with Ionic without changing the way you did a few things.

When using Ionic with Vue, this (likely) won’t be the case. There will be no special Ionic behaviour that modifies the way Vue works by default – you would use normal Vue routing and Ionic components will just be dropped in on top.

It will (likely) be possible to still use the push/pop style navigation that the NavController from Ionic provides with Vue (as the NavController will also be ported to a web component), but it will (likely) be best to stick to doing things the normal “Vue way”.

For these reasons, I think it makes the most sense to focus on learning the basics of Vue first without considering anything specific to Ionic (but still keeping it in the context of Ionic and differences to Angular).

In this tutorial series, I intend to introduce the basics of building Vue applications to those who are already familiar with using Angular. If you are not already familiar with Angular then this introduction to Vue will likely not be that useful to you, as a lot of comparisons to Angular will be made.

Getting Started

Like Angular, Vue also provides a convenient CLI tool that you can use to easily generate a new Vue application with everything configured for you. We’re going to quickly walk through installing the CLI and generating a new Vue project, and then we will briefly walk through the basic application structure.

Install the Vue CLI with the following command:

npm install -g vue-cli

Create a new Vue project using the following command:

vue init webpack my-project

This will create a new project using the webpack template, which has all the configuration for webpack, a development server, and more set up by default. Once the project has been created you will need to make it your working directory:

cd my-project

and then install all of the dependencies:

npm install

Once that is done, you will be able to serve the application using:

npm run dev

Application Structure (in Brief)

In the first part of this series I want to focus mainly on the syntax differences (and similarities) between Angular and Vue, but I think it will help to first have a basic understanding of the project structure. I am going to fly through this right now, we will likely discuss it in more detail later.

The structure of a Vue application is much the same as an Angular application – there is (usually) a single root component which contains all of the other components for the application (each of which may then have their own components and so on). This creates a tree-like structure of components.

If you take a look at the index.html file of your generated Vue project you will see the following element:

<div id="app"></div>

this is the element that your Vue application will be set up on. If you then take a look at the src/main.js file.

import Vue from 'vue';
import App from './App';

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App },
});

You can see we are creating a new Vue application on the #app element. This has a template of <App/> which is just another component (that is being set up using the components property). Again, this is pretty much the exact way that Angular works – in this case, our root component is App. We can look at that component in src/App.vue, and it will look something like this:

<template>
  <div id="app">
    <img src="./assets/logo.png" />
    <HelloWorld />
  </div>
</template>

<script>
  import HelloWorld from './components/HelloWorld';

  export default {
    name: 'app',
    components: {
      HelloWorld,
    },
  };
</script>

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

There are all the ingredients you would expect to see in a component for an Angular application:

  • A template to define the view
  • Javascript to define application logic
  • Style definitions

but when building Ionic applications in Angular, most people would have these three things in separate files, i.e:

  • some-component.html
  • some-component.ts
  • some-component.scss

but in this case, everything is contained within the one file. We are also importing (just like we would in Angular) another component called HelloWorld that has been added to the template for the App component. This makes HelloWorld a child component of App, and you can find it at src/components/HelloWorld.vue:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li>
        <a href="https://chat.vuejs.org" target="_blank">Community Chat</a>
      </li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
      <br />
      <li>
        <a href="http://vuejs-templates.github.io/webpack/" target="_blank"
          >Docs for This Template</a
        >
      </li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li>
        <a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a>
      </li>
      <li>
        <a href="https://github.com/vuejs/awesome-vue" target="_blank"
          >awesome-vue</a
        >
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    name: 'HelloWorld',
    data() {
      return {
        msg: 'Welcome to Your Vue.js App',
      };
    },
  };
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1,
  h2 {
    font-weight: normal;
  }

  ul {
    list-style-type: none;
    padding: 0;
  }

  li {
    display: inline-block;
    margin: 0 10px;
  }

  a {
    color: #42b983;
  }
</style>

Basically the same idea here as the root component, it’s just a little more complex. There is a data() function defined which sets up a msg value that can then be used inside of the template, using the same interpolation syntax as Angular {{ }} (more on this later). Also note that the scoped attribute is added to the style block, which will scope those styles to just this component.

This was just a very quick rundown of how a Vue application works, but it should give you a sense of the overall architecture and how it compared to Angular.

Angular Syntax vs Vue Syntax

Whilst Vue and Angular are clearly two very different frameworks, when you start looking into the syntax differences you will likely feel quite at home. The concepts and syntax are very similar, and it’s going to make it a lot easier to slot (that’s a little pun for later) into the Vue way of doing things if you already understand Angular.

In this section, we are going to be looking at the similarities and differences between Vue and Angular when it comes to template syntax. A lot of Vue’s template syntax was inspired by Angular (in their opinion, Angular “got it right”) so you are going to notice a lot of similarities.

Data Binding

In Angular, we could bind any of our class members inside of our template, in Vue we can use any of the values defined in the data() function for the component:

export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
    };
  },
};

This will make a variable called msg available to be used in the template. In order to make use of that variable, in Angular, we would use square brackets to bind to it, like this:

<span [title]="msg"></span>

but in Vue we need to use v-bind, like this:

<span v-bind:title="msg"></span>

You can also use double curly braces just like you can in Angular to render some data to the template:

{{ msg }}

Conditional Rendering

The ability to easily control what is and isn’t displayed in our templates based on some conditions, or looping over a set of data to create new elements, is a powerful part of Angular. Vue implements the same style of conditional rendering.

In Angular, if we wanted to display a paritcular element based on some condition we would use the *ngIf structural directive:

<div *ngIf="someBoolean"></div>

but in Vue, we would use v-if:

<div v-if="someBoolean"></div>

If we want to loop over a set of data and render an element for each item in the set, we would use the *ngFor structural directive in Angular:

<div *ngFor="let article of articles">{{ article.title }}</div>

but in Vue, we just need to use v-for:

<div v-for="article in articles">{{ article.title }}</div>

In both cases, we can access the data stored on each item using the same interpolation syntax that Angular uses. There are other options available as well, like using if/else conditions in templates, but we’re going to leave it there for now.

Event Binding

Most applications will need to listen for and handle some events – like a click on a particular element. In Angular, you would be used to doing something like this:

<button (click)="doSomething()"></button>

and once again Vue is quite similar, except that we use v-on instead (we can also use @ as a shortcut for this):

<button @click="doSomething"></button>

By passing in the method name, this would invoke the doSomething function on the component. We don’t have any methods defined in our generated example, but it might look something like this:

export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
    };
  },
  methods: {
    doSomething() {
      this.msg = 'We did it!';
    },
  },
};

Props

In Vue, a prop is basically the same idea as @Input in Angular. It is a way to pass data from a parent component to a child component. In Angular, you would define an input like this:

@Input('myInput') myInput;

This would then allow you to bind a value to that input when using the component, for example:

<my-component [myInput]="someValue"></my-component>

In Vue, we would define props on the component for data that we want to pass in. To create a prop, we might modify the component to look like this:

export default {
  name: 'HelloWorld',
  props: ['myProp'],
  data() {
    return {
      msg: 'Welcome to Your Vue.js App',
    };
  },
};

This would then allow us to attach a myProp attribute to the HelloWorld component:

<HelloWorld myProp="hello!" />

We could then access that value inside of the HelloWorld component, for example we might render it out to the template with:

<h2>{{ myProp }}</h2>

which would display hello! on the screen.

Slots

The final concept I want to touch on is slots and, once again, it is analogous to a concept in Angular. In Angular, we use the concept of content projection to “project” content that is supplied to a component into the template. As a simple example, we can do the following:

<h2>Some content is going to be injected below!</h2>
<ng-content></ng-content>
<h2>Some content is going to be injected above!</h2>

If we add this to the template of a component, then anything content that is supplied to that component will be injected where the <ng-content> tags are. So, if we did the following:

<my-component> We'll do it live! </my-component>

The template for the component would become:

<h2>Some content is going to be injected below!</h2>
We'll do it live!
<h2>Some content is going to be injected above!</h2>

Slots in Vue behave almost identically. Instead, we just use <slot> instead of <ng-content>. If we were to add the following to the template for a component:

<slot></slot>

and then we add some content to that component:

<HelloWorld> Put me in the slot! </HelloWorld>

The “Put me in the slot!” text will be injected into the template wherever <slot></slot> is.

Summary

There’s always going to be a bit of learning curve when picking up a new framework, and you’ll have to spend time messing around with the basics again, but if you’re already familiar with Angular then you’ll have a bit of a head start with Vue.

In the spirit of keeping things simple for now, not everything I have mentioned in this post is strictly best practice. It would be beneficial to familiarise yourself with this style guide.

In later tutorials in this series, we will continue learning important Vue concepts and eventually build an Ionic application in Vue.

Learn to build modern Angular apps with my course