September 30, 2020
  • All
  • Engineering
  • Tutorials
  • Ionic
  • Vue

Vue 3 for Ionic Developers

Mike Hartington

Director of Developer Relation...

The other week, the Vue team released a major update to VueJs, its 3.0.0 release. We (Ionic) have been following Vue for some time now and keeping an eye out for when their v3 would be ready in order to complete Ionic Vue support. As we stand right now, Ionic Vue is going through its beta release with a release candidate very close. With everything coming together and Ionic devs getting another framework they could use, I thought it would make sense to give an overview of Vue for those who are curious if it’s the right framework for them. Let’s dive in.

Components All The Way

Like React and Angular, Vue is built on the concept of Components. From the root of your app, to the routes that are rendered, everything is a component.

Now this isn’t too far off from what other frameworks do, but with Vue, these components are built as Single File Components. These are files with the .vue extension, and they are how we create our template, styles, and component logic. Let’s look at a basic component.

<template>
  <h1>Hello, {{ name }}</h1>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  setup() {
    const name = "world"
    return {name}
  }
});
</script>

<style scoped>
h1 {
  font-family: Avenir, Helvetica, Arial, sans-serif;
}
</style>

Let’s break this down.

Templates

For starters, we have this template tag at the top of our file. As its name implies, this is the template for our component, which will be what gets rendered in the DOM.

<template>
  <h1>Hello, {{ name }}</h1>
</template>

We have a common pattern of double curly braces ({{ }}) to declare that this value will be derived from our component’s logic.

Scripts

Speaking of, let’s look at the next piece, the script tag.

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
  setup() {
    const name = "world"
    return {name}
  }
});
</script>

First off, a script tag embedded in our component? What about separation of concerns? With SFCs, the idea is to keep all the necessary pieces of a component together, instead of split across multiple files. This way, our component has everything it needs in one place.

Next, what’s the deal with the lang attribute on the script tag? With Vue and its tooling, we can author our components logic in either JavaScript or TypeScript. By default, the lang is set to js for JavaScript, but TypeScript can be enabled by setting lang to ts. Now, when the tooling for Vue parses our code, it will know to run the script segment through TypeScript first.

For the logic of our component, we have a default export and this defineComponent function. In Vue, a component’s logic is really just an object that gets exported. But since we’re using TypeScript, a regular object doesn’t really provide the correct types for tooling. So by using defineComponent, we are essentially returning an object, just with the right type information for TypeScript. Even if you are authoring things in JavaScript, it’s best practice to use defineComponent for consistency.

Now the main piece of our component logic is the setup function. This allows us to compose functionality together, bringing in external utilities into our component in a modular fashion. There’s a good section in the Vue docs that covers composition and I highly suggest giving it a read.

Style

<style scoped>
h1 {
  font-family: Avenir, Helvetica, Arial, sans-serif;
}
</style>

The last section of our component is the style tag. Like script, we can pass different style preprocessors in the lang attribute. So if you want to build your components using something like Sass, Less, or any other preprocessor, you can specify that in lang. In addition to this, you can also specify how your component’s styles will be scoped. By default, styles are part of the global CSS context, meaning any CSS written in styles could conflict with one another. But if you add the scope attribute, a component’s style will be limited to that component only.

Bootstrapping an App

With a component create, we can bootstrap an app by targeting an HTML element and rendering the component:

import { createApp } from 'vue';
import App from './App.vue';

createApp(App)
  .mount('#app');

createApp is a function from Vue that will bootstrap the app for us. This will return an instance of our app, which we can render with mount. mount just takes an HTML selector for our root. In a typical Vue app structure, this is a div in our index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
  ...
  </head>
  <body>

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

  </body>
</html>

From here, our app is up and running!

Diving Deeper

Vue provides the same functionality that users would expect from a modern JavaScript framework, like routing, state management, and a CLI. But these tools are all optional, and not a hard requirement. So if you wanted to get started, you could roll your own solutions, or install the Vue CLI and add the features you need.

If you’re interested in learning more about Vue, especially Vue 3, take a look at the new Vue 3 docs, which covers not only the basics of Vue’s component syntax, but deep dives into component architecture, external libraries, and overall best practices. We’re thrilled to see Vue 3 launch, and can’t wait to complete Ionic Vue. Cheers!


Mike Hartington

Director of Developer Relation...