Build Your First Ionic Vue App
Tags: ionic, tutorial, vue, javascript
Published: 2019-12-13 04:23:56


[See Ionic Framework Vue JS eBook & Video Courses]
(https://gumroad.com/fiwic)


## Overview
This is documentation to duplicate the sample application described in the Ionic Framework documentation react, but in this case, using [vue js](https://vuejs.org/). 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](https://ionicframework.com/docs/react/your-first-app) which goes into a level of detail not covered here.
>[@ionic/vue](https://github.com/ionic-team/ionic/tree/master/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`](https://cli.vuejs.org/) 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
```
make the base app call `my-app` using the `vue-cli`; pick the default settings
```
vue create my-app
```
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
```
## A look at a Vue Application Structure
### Start with `main.js`
If you open up `main.js` you will see the following.
```javascript
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
```
We will need to add some ionic code here
```javascript
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')
```
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](https://router.vuejs.org/)

Lets next move over to the `App.vue` and clean it up to include the basics need code to support the ionic-router.
```vue
<template>
  <div id="app">
    <ion-app>
      <ion-vue-router />
    </ion-app>
  </div>
</template>

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

<style>
</style>
```
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
```javascript
// router
import { IonicVueRouter } from "@ionic/vue";
Vue.use(IonicVueRouter);
```
Now let add the basic route pointing to our home page; notice the use of the custom vue router for ionic.
```javascript
const router = new IonicVueRouter({
  routes: [
    { path: "/", redirect: "/home" },
    {
      path: "/home",
      name: "home",
      component: () =>
        import(/* webpackChunkName: "home" */ "@/components/HomePage"),
    }
  ]
});
```
First we state that the default route should redirect to home route
```javascript
    { path: "/", redirect: "/home" },
```
Then we specify the home route and lazy load the `HomePage` component
>See: [Lazy Loading Routes](https://router.vuejs.org/guide/advanced/lazy-loading.html) in vuejs in the [vuejs.org](vuejs.org) documentation.
```javascript
    {
      path: "/home",
      name: "home",
      component: () =>
        import(/* webpackChunkName: "home" */ "@/components/HomePage"),
    }
```
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.
```javascript
new Vue({
  router,
  render: h => h(App)
}).$mount("#app");
```
## Our First Ionic Page
This page, the `HomePage.vue` component is the `vue` version of the page described here in the [Ionic Documentation](https://ionicframework.com/docs/react/your-first-app#a-component-with-style)
>Note that in `vue` we do not use camel case, but use hyphens instead.
```vue
<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>
```
### 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 the`ion-fab-button` component.
```javascript
import { add } from "ionicons/icons";
import { addIcons } from "ionicons";
addIcons({
  "ios-add": add.ios,
  "md-add": add.md
});
```
<img src="https://thepracticaldev.s3.amazonaws.com/i/1bxbk27563drpnc4ruum.png"  width="350">
### 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](https://router.vuejs.org/) responding to a click event on the button.
```vue
<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>
```
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
```javascript
{
  path: "/new-item",
  name: "new-item",
  component: () =>
    import(/* webpackChunkName: "new-item" */ "@/components/NewItemPage"),
}
```
### 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
```vue
<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>
```
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
```vue
<ion-buttons slot="start">
  <ion-back-button default-href="/"></ion-back-button>
</ion-buttons>
```
This code will put the button in the header and handle the appropriate navigation without any additional code.
<img src="https://thepracticaldev.s3.amazonaws.com/i/1f2d5fhxgy03apizcing.png"  width="350">
## Build a Native App
>The following overview is from the Official Ionic Documentation: [See Documentation](https://ionicframework.com/docs/react/your-first-app#build-a-native-app)

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.
- https://capacitor.ionicframework.com/docs/getting-started/

```console
npm install --save @capacitor/core @capacitor/cli
```

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

```
npx cap init --web-dir=dist
```

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
```
Now you need to build the application for production so it can get bundled for deployment.
```
yarn run build
```
> 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
```html
<meta
  name="viewport"
  content="width=device-width, initial-scale=1, shrink-to-fit=no , viewport-fit=cover"
/>
```
And finally there is a need for some css in the `App.vue` file
```css
<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>
```
To Push App Updates you can run the following commands.
- `yarn run build; npx cap sync` 

## Project Source Code

{% github aaronksaunders/my-first-ionic-app-vue %}

### Video Playlist On Vue and Vue Composition API

{% youtube 3MLHCRep_MM %}


>### About Clearly Innovative
[Clearly Innovative](www.clearlyinnovative.com) 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](www.in3dc.com), 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!