Tutorial

Using Ionic 4 Components in Your Vue.js Apps

Published on January 16, 2018
Using Ionic 4 Components in Your Vue.js Apps

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Vue.js is gaining popularity for all the right reasons, and the future looks bright for Vue and the combination of Progressive Web Applications. Ionic is a web framework at the forefront of combining mobile-first UX and although it’s currently powered by Angular 5.x, the team’s new Stencil compiler allows Vue.js to use the same Web Components with Ionic 4.

Ionic 4 is currently in alpha and should not be used in production, but nevertheless, this is a great thought experiment and dives deep into the benefits of Stencil and what Web Components mean for framework agnostic UI components.

To get started, create a new Vue project with the Vue CLI:

# Install the Vue CLI
$ npm install vue-cli

# Create a new Vue project
$ vue init webpack-simple vue-ionic

# Change directory
$ cd vue-ionic

# Add vue-router and axios
$ npm install vue-router axios

# Run development server
$ npm run dev

REST API

We can make a local REST API with json-server which allows us to easily GET and POST todos to our server. Install this globally on your machine if you haven’t got it already:

$ npm install json-server -g

The server can be started with a JSON serialized database. Create a file named db.json inside of the root of your project:

db.json

```json { “todos”: [ { “id”: 1, “name”: “Make awesome applications” }, { “id”: 2, “name”: “Play squash” }, { “id”: 3, “name”: “Deadlift” }, { “id”: 4, “name”: “Squat” } ] } ```

Start the API by running the following in the terminal:

$ json-server db.json --watch --port 3001

Now that we have an API up and running, let’s add Ionic!

Adding Ionic

To add an alpha version of Ionic inside of our project, adding the following script to our index.html file:

<script src="https://unpkg.com/@ionic/core@0.0.2-30/dist/ionic.js"></script>

You can find the current version of Ionic core here: https://www.npmjs.com/package/@ionic/core

At the same time, ensure you’ve got the appropriate responsive meta tag:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Routes

We can then set up two routes that allow us to either view todo items or add todo items:

App.vue
import Vue from 'vue'
import VueRouter from 'vue-router';

import TodoList from './components/TodoList';
import AddTodoItem from './components/AddTodoItem';

Vue.use(VueRouter);

const routes = [
  { path: '', redirect: '/todos'},
  { path: '/todos', component: TodoList },
  { path: '/todos/add', component: AddTodoItem}
]

export default new VueRouter({ routes })

Afterward, add the router configuration to our main Vue instance inside of main.js:

main.js
import Vue from 'vue'
import App from './App.vue'

import router from './router'

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

Ionic Web Components

As Ionic 4.x is built using Web Components, we’ll need to tell Vue that the ion- components aren’t Vue components. Inside of main.js, add the following configuration object that ignores all Ionic elements:

main.js
Vue.config.ignoredElements = [/^ion-/]

Inside of App.vue we can now add our <router-view> and enclose this in an <ion-app> component. This is used to enclose all of our Ionic components:

App.vue
<template>
  <ion-app>
    <router-view></router-view>
  </ion-app>
</template>

Todo List

To create the todo list page that we registered inside of router.js, create a file named TodoList.vue inside of the src/components folder.

Inside of our created hook, we’re capturing the todos from our API and assigning them to the todos array.

TodoList.vue
import axios from 'axios';

export default {
  data() {
    return {
      todos: []
    }
  },
  methods: {
    addTodo() {
      this.$router.push({path: '/todos/add'})
    }
  },
  created() {
    axios.get('http://localhost:3001/todos')
      .then(res => this.todos = res.data)
  }
}

We can then add a template which will certainly look similar to anyone that’s used Ionic in the past:

<template>
  <ion-page>
    <ion-header>

      <ion-toolbar class="toolbar-md-primary">
        <ion-title>TodoList</ion-title>
      </ion-toolbar>

    </ion-header>
    <ion-content class="content">

      <ion-list>
        <ion-item v-for="todo in todos" :key="todo.id">
          {{todo.name}}
        </ion-item>
      </ion-list>

      <ion-fab-button class="todo-fab" @click="addTodo">
        <ion-icon name="add"></ion-icon>
      </ion-fab-button>
    </ion-content>
  </ion-page>
</template>

We wrap our component inside of an ion-page element. This then allows us to define a header and toolbar which gives us the ability to display a navigation bar.

Next, we can display the list inside of an ion-content element and iterate over each item inside of our todos array as an ion-item.

To style our fab button and add some padding. We’ll be using both classes across both of our components so let’s add a style.css file and the appropriate classes:

style.css
.todo-fab {
  position: fixed;
  bottom: 25px;
  right: 15px;
  font-size: 30px;
}

.content {
  padding: 10px 10px 10px 0px
}

This gives us the following result(s)

List of todo items

When the user clicks the FAB button, they’ll be navigated to the Add Todo page. Let’s create that at components/AddTodoItem.vue:

AddTodoItem.vue
<template>
  <ion-page>
    <ion-header class="toolbar-md-primary">

      <ion-toolbar>
        <ion-title>Add Item</ion-title>
      </ion-toolbar>

    </ion-header>
    <ion-content class="content">

      <ion-item>
        <ion-input :value="name" ref="newTodoItem" @input="updateTodoName" placeholder="Todo Name"></ion-input>
      </ion-item>

      <ion-fab-button class="todo-fab" @click="addTodo">
        <ion-icon name="checkmark"></ion-icon>
      </ion-fab-button>

    </ion-content>
  </ion-page>
</template>

Our markup looks quite similar, but this time we’re using an ion-input. To get the value of the new todo item we’re using a ref and an input event.

import axios from 'axios';

export default {
  data() {
    return {
      name: ''
    }
  },
  methods: {
    addTodo() {
      const newTodo = { name: this.name }
      axios.post('http://localhost:3001/todos', newTodo)
        .then(res => {
          this.$router.push({path: '/todos'})
        })
    },
    updateTodoName() {
      this.name = this.$refs.newTodoItem.value
    }
  }
}

The code for this page is quite similar too, we’re adding a new Todo item to our API using axios whenever someone clicks the FAB button.

Here’s the results

Adding a todo item

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel