Using Vue.js (v3 Beta) with Ionic Components & Capacitor Plugins

Aaron K Saunders - Sep 7 '20 - - Dev Community

See My Upcoming Book On Ionic & Vue JS


Update from original post Jan 2019 which was based on Vue.js version 2 https://dev.to/aaronksaunders/mobile-development-w-vuejs-and-ionic-capacitor-plugins-5fb5

Overview

This sample/tutorial will walk through the integration of the following features in an Ionic Capacitor web/mobile application using the latest version Ionic Framework Vue.js Components and Vue.js, version three which is still in beta.

Vue3 Ionic Video Playlist Available Here

I am also using the latest beta release of the Ionic integration with Vue. I am using typescript in the example and relying heavily on the new pattern of composition when creating single file components.

The Video...

Whats Covered...

created project using latest cli from Ionic using ionic start --tag vue-beta

Alt Text

🔆Click Here for Ionic Framework ReactJS and VueJS Tips/Tutorials?🔆

Basic Page Structure

A bit different than in the past, please see comments in the code below and the important points highlighted at end of section.

Main thing to notice, there is no data, methods, etc sections any more, it is all handled in the setup

<script lang="ts">
// import components from ionic
import {
  IonContent,
  IonHeader,
  IonPage,
  IonTitle,
  IonToolbar,
} from "@ionic/vue";

// import capacitor plugins
import { Plugins, CameraSource, CameraResultType } from "@capacitor/core";
const { Camera } = Plugins;

// import from vue
import { defineComponent, ref } from "vue";

// import to get access to the router
import { useRouter } from "vue-router";

// define the component
export default defineComponent({

  // provide the name
  name: "Home",

  // provide the list of components being used in the
  // template
  components: {
    IonContent,
    IonHeader,
    IonPage,
    IonTitle,
    IonToolbar,
  },

  // setup function, It is called after props resolution, when 
  // instance of the component is created.
  setup() {
    const imageUrl = ref<string | null>();

    // get access to router
    const router = useRouter();

    // functions
    const nextPage = () => { };
    const takePicture = async () => { };

    // return the props and functions to component
    // so they are accessible in the template
    return {
      takePicture,
      imageUrl,
      nextPage,
    };
  },
});
</script>
Enter fullscreen mode Exit fullscreen mode

Important Points

  • there is no access to this in the setup() function
// old way
this.$router.push("/next-page");

// new way
const router = useRouter();
router.push("/next-page");
Enter fullscreen mode Exit fullscreen mode
  • everything that is returned from the setup() function is available to use in the template.
    Alt Text

  • values/properties defined using ref are accessible without a need to unwrap in template but you must use imageUrl.value when accessing in a function

<!-- in template -->
<div class="ion-padding">
   <img :src="imageUrl ? imageUrl : null" />
</div>
Enter fullscreen mode Exit fullscreen mode
// in function
console.log(imageUrl.value);
Enter fullscreen mode Exit fullscreen mode

Capacitor Plugins Support

Plugins are imported and utilized the same as they were in the previous version. The one difference you will notice is how the data properties are accessed.

Here is the code for using the Camera plugin in the application.

// import
import { Plugins, CameraSource, CameraResultType } from "@capacitor/core";
const { Camera } = Plugins;

// code inside of `setup()`
const takePicture = async () => {
  try {
    const image = await Camera.getPhoto({
      quality: 90,
      allowEditing: true,
      resultType: CameraResultType.DataUrl,
      source: CameraSource.Prompt,
    });
    console.log("image", image);
    // image.base64_data will contain the base64 encoded 
    // result as a JPEG, with the data-uri prefix added
    // unwrap to set the `value`
    imageUrl.value = image.dataUrl;

    // can be set to the src of an image now
    console.log(image);
  } catch (e) {
    console.log("error", e);
  }
};
Enter fullscreen mode Exit fullscreen mode

Capacitor PWA Support

Same as before just be sure to include the library and call defineCustomElements(window); after component is mounted

//main.ts
import { defineCustomElements } from '@ionic/pwa-elements/loader';


const app = createApp(App)
  .use(IonicVue)
  .use(router);

router.isReady().then(() => {
  app.mount('#app');

  defineCustomElements(window);
});
Enter fullscreen mode Exit fullscreen mode

CLI Integration

You can now use the same ionic commands for building and running your application since vue support is integrated in the CLI

Source Code

GitHub logo aaronksaunders / capacitor-vue3-ionicv5-app

[NEW] Sample app using capacitor vuejs version 3 and ionic v5 BETA components

VueJS Ionic Capacitor Sample Application - Vue3 Ionic BETA

Updated 9/3/2020

  • Features: Tabs, Capacitor Plugins Camera, GeoLocation
Ionic:

   Ionic CLI       : 6.11.8-testing.0 (/Users/aaronksaunders/.nvm/versions/node/v13.9.0/lib/node_modules/@ionic/cli)
   Ionic Framework : @ionic/vue 5.4.0-dev.202009032307.949031e

Capacitor:

   Capacitor CLI   : 2.4.0
   @capacitor/core : 2.4.0

Utility:

   cordova-res (update available: 0.15.1) : 0.11.0
   native-run                             : 1.0.0

System:

   NodeJS : v13.9.0 (/Users/aaronksaunders/.nvm/versions/node/v13.9.0/bin/node)
   npm    : 6.13.7
   OS     : macOS Catalina

Camera Working In PWA/Website

Geolocation using Core Capacitor Plugins

Using Typescript

Using Composition Pattern for Components

🔆Click Here for Ionic Framework ReactJS and VueJS Tips/Tutorials?🔆

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .