DEV Community

Cover image for Build Your First Ionic Vue App
Aaron K Saunders
Aaron K Saunders

Posted on • Updated on

Build Your First Ionic Vue App

See Ionic Framework Vue JS eBook & Video Courses

Overview

This is documentation to duplicate the sample application described in the Ionic Framework documentation react, but in this case, using vue js. You can follow along with the specific details of what the ionic web components are doing by looking at the Build Your First Ionic React App - Overview Documentation which goes into a level of detail not covered here.

@ionic/vue combines the core Ionic experience with the tooling and APIs that are tailored to Vue Developers. Currently in beta.

Creating a project with the Ionic CLI

Since you cannot at this point use the ionic-cli to create your application, we will use the vue-cli and then add the additional ionic libraries and dependencies that you need to get your project running.

let's get the latest ionic

npm install -g ionic@latest
Enter fullscreen mode Exit fullscreen mode

make the base app call my-app using the vue-cli; pick the default settings

vue create my-app
Enter fullscreen mode Exit fullscreen mode

now add all of the specific ionic libraries, please notice the specific use of the version.

yarn add @ionic/vue@0.0.9
yarn add @ionic/core
yarn add vue-router
Enter fullscreen mode Exit fullscreen mode

A look at a Vue Application Structure

Start with main.js

If you open up main.js you will see the following.

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

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
Enter fullscreen mode Exit fullscreen mode

We will need to add some ionic code here

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

import Ionic from "@ionic/vue"
import "@ionic/core/css/core.css"
import "@ionic/core/css/ionic.bundle.css"


Vue.config.productionTip = false;
Vue.use(Ionic);

new Vue({
  render: h => h(App),
}).$mount('#app')
Enter fullscreen mode Exit fullscreen mode

We needed to add the additional styling that is provided for the ionic components.

Let's Get Routing Working

Additional information on vue-router is available here Vue Router Documentation

Lets next move over to the App.vue and clean it up to include the basics need code to support the ionic-router.

<template>
  <div id="app">
    <ion-app>
      <ion-vue-router />
    </ion-app>
  </div>
</template>

<script>
export default {
  name: "app"
};
</script>

<style>
</style>
Enter fullscreen mode Exit fullscreen mode

Now we need to go back to main.js and add the default route which will point to the HomePage.vue component.

Lets add the imports to support the custom ionic-vue-router

// router
import { IonicVueRouter } from "@ionic/vue";
Vue.use(IonicVueRouter);
Enter fullscreen mode Exit fullscreen mode

Now let add the basic route pointing to our home page; notice the use of the custom vue router for ionic.

const router = new IonicVueRouter({
  routes: [
    { path: "/", redirect: "/home" },
    {
      path: "/home",
      name: "home",
      component: () =>
        import(/* webpackChunkName: "home" */ "@/components/HomePage"),
    }
  ]
});
Enter fullscreen mode Exit fullscreen mode

First we state that the default route should redirect to home route

    { path: "/", redirect: "/home" },
Enter fullscreen mode Exit fullscreen mode

Then we specify the home route and lazy load the HomePage component

See: Lazy Loading Routes in vuejs in the vuejs.org documentation.

    {
      path: "/home",
      name: "home",
      component: () =>
        import(/* webpackChunkName: "home" */ "@/components/HomePage"),
    }
Enter fullscreen mode Exit fullscreen mode

Now that we have the router object initialized, we need to make it accessible to all vue components in the application. To do that, we need to pass the router as a property on the Vue object at initialization.

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

Our First Ionic Page

This page, the HomePage.vue component is the vue version of the page described here in the Ionic Documentation

Note that in vue we do not use camel case, but use hyphens instead.

<template>
  <ion-page>
    <ion-header>
      <ion-toolbar color="primary">
        <ion-title>Home</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content padding>
      <ion-list>
        <ion-item>
          <ion-checkbox slot="start"></ion-checkbox>
          <ion-label>
            <h1>Create Idea</h1>
            <ion-note>Run Idea by Brandy</ion-note>
          </ion-label>
          <ion-badge color="success" slot="end">5 Days</ion-badge>
        </ion-item>
      </ion-list>
      <ion-fab vertical="bottom" horizontal="end" slot="fixed">
        <ion-fab-button >
          <ion-icon name="add" />
        </ion-fab-button>
      </ion-fab>
    </ion-content>
  </ion-page>
</template>

<script>
import { add } from "ionicons/icons";
import { addIcons } from "ionicons";
addIcons({
  "ios-add": add.ios,
  "md-add": add.md
});
export default {
  name: "HomePage",
  props: {
    msg: String
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Enter fullscreen mode Exit fullscreen mode

Adding the Icons

You will notice that the code here is handling the icons a bit different than there are being handled in the reactjs version.

1) Import individually the icons that you want to used from ionicons.
2) Load them up using addIcons.

In the example below we are using the "add" icon to render in theion-fab-button component.

import { add } from "ionicons/icons";
import { addIcons } from "ionicons";
addIcons({
  "ios-add": add.ios,
  "md-add": add.md
});
Enter fullscreen mode Exit fullscreen mode

Using the Router

If you noticed we have a button on the page and we would like the page to navigate to the next page when the user clicks on it. We can handle that using the vue-router responding to a click event on the button.

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
  <ion-fab-button @click="$router.push({ name: 'new-item' })">
    <ion-icon name="add" />
  </ion-fab-button>
</ion-fab>
Enter fullscreen mode Exit fullscreen mode

Since we added the router to the Vue instance in main.js we have access to it in our components using $router. When the user clicks the button, we are telling the router to route to the new path with the name new-item that we will define as a named route in main.js.
Lets go back to main.js and add the route.

Adding a new Route

Adding the Route To the Router Object

{
  path: "/new-item",
  name: "new-item",
  component: () =>
    import(/* webpackChunkName: "new-item" */ "@/components/NewItemPage"),
}
Enter fullscreen mode Exit fullscreen mode

Adding the Page Associated to the Route

The new page will follow the same structure of header, toolbar content as the other page, but we need to handle the back button functionality.

Lets create a new component called NewItemPage.vue and add it to the components path.
Add the following code to the file

<template>
  <ion-page>
    <ion-header>
      <ion-toolbar color="primary">
        <ion-buttons slot="start">
          <ion-back-button default-href="/"></ion-back-button>
        </ion-buttons>
        <ion-title>New Item</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content padding></ion-content>
  </ion-page>
</template>

<script>
export default {
  name: "NewItemPage",
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Enter fullscreen mode Exit fullscreen mode

The page is pretty straight forward based on what we have seen so far, except we need to add the back button, luckily ionic has something for that

<ion-buttons slot="start">
  <ion-back-button default-href="/"></ion-back-button>
</ion-buttons>
Enter fullscreen mode Exit fullscreen mode

This code will put the button in the header and handle the appropriate navigation without any additional code.

Build a Native App

The following overview is from the Official Ionic Documentation: See Documentation

We now have the basics of an Ionic React app down, including some UI components and navigation. The great thing about Ionic’s components is that they work anywhere, including iOS, Android, and PWAs. To deploy to mobile, desktop, and beyond, we use Ionic’s cross-platform app runtime Capacitor. It provides a consistent, web-focused set of APIs that enable an app to stay as close to web-standards as possible while accessing rich native device features on platforms that support them.

Installing Capacitor

For more detailed information follow the instructions provided here.

npm install --save @capacitor/core @capacitor/cli
Enter fullscreen mode Exit fullscreen mode

With VueJS the web asset directory is build you can set this when initializing the app

npx cap init --web-dir=dist
Enter fullscreen mode Exit fullscreen mode

Otherwise update the web assets directory in the capacitor.config.json file to include the following "webDir": "dist"

You will then get prompted to answer some questions about your app; for example:

npx cap init --web-dir=build
? App name myAppCap
? App Package ID (in Java package format, no dashes) com.aks.mycapapp
✔ Initializing Capacitor project in /Users/aaronksaunders/dev/projects/vuejs/my-app in 23.41ms


🎉   Your Capacitor project is ready to go!  🎉

Add platforms using "npx cap add":

  npx cap add android
  npx cap add ios
  npx cap add electron

Follow the Developer Workflow guide to get building:
https://capacitor.ionicframework.com/docs/basics/workflow
Enter fullscreen mode Exit fullscreen mode

Now you need to build the application for production so it can get bundled for deployment.

yarn run build
Enter fullscreen mode Exit fullscreen mode

I ran into version issues at this point and needed to run the following command to updated core-js library npm install --save core-js

Then add your platform by running the appropriate command

  • Now you can run npx cap add ios add ios
  • Now you can run npx cap add android add android

Then launch the application

  • Now you can run npx cap open ios to launch Xcode
  • Now you can run npx cap open android to launch Android Studio

Steps to Fix Header Issues to account for the safe-area/notch on newer iphones; make the following change to the index.html file in the public directory of the project

<meta
  name="viewport"
  content="width=device-width, initial-scale=1, shrink-to-fit=no , viewport-fit=cover"
/>
Enter fullscreen mode Exit fullscreen mode

And finally there is a need for some css in the App.vue file

<style>
    ion-navbar.toolbar.toolbar-ios.statusbar-padding,
    ion-navbar.toolbar-ios ion-title.title-ios,
    ion-toolbar.toolbar.toolbar-ios.statusbar-padding,
    ion-toolbar.toolbar-ios ion-title.title-ios {
      padding-top: constant(safe-area-inset-top);
      padding-top: env(safe-area-inset-top);
    }
</style>
Enter fullscreen mode Exit fullscreen mode

To Push App Updates you can run the following commands.

  • yarn run build; npx cap sync

Project Source Code

GitHub logo aaronksaunders / my-first-ionic-app-vue

Your First Ionic App: Vue - trying to mimic the React JS documentation from Ionic Website but with Vue

Video Playlist On Vue and Vue Composition API

About Clearly Innovative

Clearly Innovative is a solutions provider that develops digital products. We shape ideas into viable products and transform client needs into enhanced technology solutions. As a leader in the early adoption and implementation of cutting-edge technologies, Clearly Innovative provides services focused on product strategy, user experience, design, and development. According to CEO, Aaron Saunders "We are not just designers and developers, but end-to-end digital solution providers." Clearly Innovative has created a tech education program, Clearly Innovative Education, whose mission is to create a world where people from underrepresented backgrounds can have a seat at the digital table as creators, innovators, and entrepreneurs.

#TheFutureIsWrittenInCode

The Future is Written in Code series, as part of Inclusive Innovation Incubator, provides introductory and advanced programming classes as well as coding courses with a focus on business and entrepreneurship. Select programming offered includes Coding, UI/UX, Coding & Business, Coding & Entrepreneurship, Business Canvassing, Entrepreneurship: Developing Your Idea into App, to name a few. Please contact info@in3dc.com to find out more!

Discussion (31)

Collapse
vuurball profile image
vuurball

Wonderful tutorial Aaron, thanks!
just one question from a total noob..
after npx cap add android how exactly can I get an apk file, so that I can actually put the app on my phone and see it there?
(without using android studio, is there a cli tool?)

Collapse
berkmann18 profile image
Maximilian Berkmann

Am I the only getting errors like:

chunk-2a882949.js?1993:13 Uncaught TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at addIcons (chunk-2a882949.js?1993:13)
    at appInitialize (ionic-vue.esm.js?481b:279)
    at Object.install (ionic-vue.esm.js?481b:619)
    at Function.Vue.use (vue.runtime.esm.js?2b0e:5107)
    at eval (main.js?56d7:12)
    at Module../src/main.js (app.js:1134)
    at __webpack_require__ (app.js:854)
    at fn (app.js:151)
    at Object.1 (app.js:1147)

In the devtools?

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Link to your project?

Collapse
berkmann18 profile image
Maximilian Berkmann
Collapse
kescript profile image
Nnamani Kester

Thanks for this article. I love it. But I have a problem. The icons are not displaying in my own setup.

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Check version number of II ionicons and ionic/vue.

Thanks for checking out my content, please take a look at videos that cover this also - youtube.com/channel/UCMCcqbJpyL3LA...

Collapse
kescript profile image
Nnamani Kester

Why not send your package.json file here, so I can see the versions

Thread Thread
aaronksaunders profile image
Aaron K Saunders Author
Collapse
kescript profile image
Nnamani Kester

I actually installed the same version like you stated i the article

Thread Thread
aaronksaunders profile image
Aaron K Saunders Author

Is there a repo somewhere I can take a peek at?

Collapse
Sloan, the sloth mascot
Comment deleted
Collapse
aaronksaunders profile image
Aaron K Saunders Author

Need more info? Screen shot? Or can you post the repo somewhere for a peek?

Collapse
daviddalbusco profile image
David Dal Busco

Thank you for the really interesting tutorial Aaron, specially for the appendix with Capacitor to cover the all process 👍

P.S.: The way ionicons are loaded in comparison to React, Angular or native is really interesting.

Collapse
aaronksaunders profile image
Aaron K Saunders Author

I think there are some things that the Ionic team will clean up before the vue integration comes out of beta; but there was a discussion thread on Reddit about this and I had the content from a class I taught so I figured I would share with the community

Collapse
Sloan, the sloth mascot
Comment deleted
Collapse
aaronksaunders profile image
Aaron K Saunders Author

🤔

Collapse
emipmttt profile image
Emiliano Pamont

Hi Arron, a question: why are you use yarn and npm to install dependencies?

Collapse
aaronksaunders profile image
Aaron K Saunders Author

You and use either one and it will work

Collapse
navjeetc profile image
Navjeet

That was nice little intro to Ionic and Vue, short and sweet. Really enjoyed building it and got it working on IOS simulator. Do you know when Ionic Vue is planned to come out of Beta?

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Thanks I am glad it worked out,

I think there is a new version of vue coming out so i suspect these components will come out of beta sometime after the next release of vue - I am already using it in a production environment...

More examples here in my repo github.com/aaronksaunders and I am working on some YouTube videos - youtube.com/channel/UCMCcqbJpyL3LA...

Collapse
noopurphalak profile image
Noopur Ramakant Phalak

Can you also share a tutorial where you can connect your Ionic app to an offline database?

Collapse
aaronksaunders profile image
Aaron K Saunders Author

did you have a database in mind

Collapse
noopurphalak profile image
Noopur Ramakant Phalak

Hi Aaron, any update of this?

Thread Thread
aaronksaunders profile image
Aaron K Saunders Author

coming soon will be the first post of the new year

Collapse
noopurphalak profile image
Noopur Ramakant Phalak • Edited on

How about SQLite database. Below is the SQLite link to github:
github.com/jepiqueau/capacitor-dat...

Collapse
aaronksaunders profile image
Aaron K Saunders Author

After you get the basics down, here is another vuejs series I have here on dev.to - VueJS Composition API Sample App w/video - DEV Community 👩‍💻👨‍💻 buff.ly/2p64FqD

Collapse
shahbhavik204 profile image
shah-bhavik204

WHen I am trying to make some changes in Homepage.vue and run on android, it doesnt show up but works fine when run on web.

Collapse
aaronksaunders profile image
Aaron K Saunders Author

is your project somewhere i can look at? what errors are in the log?

Collapse
padakipavan profile image
padaki-pavan

Omg that's a lot of code. I recommend you to try flutter, it's amazing.

Collapse
aaronksaunders profile image
Aaron K Saunders Author • Edited on

also it is actually it isnt...

github.com/aaronksaunders/my_first...

      15 ./new_item_page.dart
      29 ./main.dart
      74 ./home_page.dart
     118 total
      23 ./App.vue
      37 ./main.js
      23 ./components/NewItemPage.vue
      45 ./components/HomePage.vue
     128 total
Collapse
aaronksaunders profile image
Aaron K Saunders Author • Edited on

Let’s not do this here