Upgrade Guide | NativeScript-Vue (original) (raw)

Upgrading from v2 to v3

Application Initialization Changes

In Vue 2, the app was initialized like this:

ts

import Vue from "nativescript-vue";
import Home from "./components/Home.vue";

new Vue({
  render: (h) => h("frame", [h(Home)]),
}).$start();

In Vue 3, you now use createApp:

ts

import { createApp } from "nativescript-vue";
import Home from "./components/Home.vue";

const app = createApp(Home);
app.start();

Key Changes:

Example Implementation

Navigation functions like $navigateTo, $navigateBack, and $showModal must now be imported instead of being accessed from this.

html

<script lang="ts" setup>
  import { <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>a</mi><mi>v</mi><mi>i</mi><mi>g</mi><mi>a</mi><mi>t</mi><mi>e</mi><mi>T</mi><mi>o</mi><mo separator="true">,</mo></mrow><annotation encoding="application/x-tex">navigateTo, </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8778em;vertical-align:-0.1944em;"></span><span class="mord mathnormal">na</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">o</span><span class="mpunct">,</span></span></span></span>navigateBack, $showModal } from "nativescript-vue";
  import MyComponent from "./components/MyComponent.vue";

  function navigate() {
    $navigateTo(MyComponent, {
      /* options */
    });
  }

  function goBack() {
    $navigateBack();
  }

  function openModal() {
    $showModal(MyComponent, {
      /* options */
    });
  }
</script>

Why the change?

Vue 3 now uses composition API and removes $navigateTo from the component instance.

Note Vue3 also supports the options API, where these methods are still available on this, however we recommend using the composition API.

Plugin Registration

Plugins are now registered using registerElement instead of modifying the Vue instance.

Before (Vue 2)

ts

import Vue from "nativescript-vue";

Vue.registerElement(
  "Gradient",
  () => require("nativescript-gradient").Gradient
);

Now (Vue 3)

ts

import { createApp, registerElement } from "nativescript-vue";
import Home from "./components/Home.vue";

registerElement("Gradient", () => require("nativescript-gradient").Gradient);

// or using import statements
import { Gradient } from "nativescript-gradient";
registerElement("Gradient", () => Gradient);

const app = createApp(Home);
app.start();

Note Some plugins export a Vue3 compatible plugin, that can be used with .use(), like @nativescript-community/ui-collectionview/vue3. Consult the plugin documentation and if it doesn't specify this, use registerElement normally.

ts

import { createApp } from "nativescript-vue";
import Home from "./components/Home.vue";
import CollectionView from "@nativescript-community/ui-collectionview/vue3";

const app = createApp(Home);
app.use(CollectionView);
app.start();

ListView Changes

  1. Instead of for="item in listOfItems", use :items="items"
  2. Instead of if="condition" us :itemTemplateSelector="function"
  3. Use #default="{ item, index }" inside <template>

Before (Vue 2)

html

<ListView for="item in listOfItems">
  <v-template>
    <label :text="item.text" />
  </v-template>

  <v-template if="item.odd">
    <label :text="item.text" class="bg-red-500" />
  </v-template>
</ListView>

Now (Vue 3)

html

<script lang="ts" setup>
  const items = ref([
    /* ... items... */
  ]);

  function itemTemplateSelector(item, index) {
    return index % 2 === 0 ? "default" : "odd";
  }
</script>

<template>
  <ListView :items="items" :itemTemplateSelector="itemTemplateSelector">
    <template #default="{ item, index }">
      <label :text="item.text" />
    </template>

    <template #odd="{ item, index }">
      <label :text="item.text" class="bg-red-500" />
    </template>
  </ListView>
</template>

🚀 Bonus: You can now strongly type item using TypeScript!

html

<template
  #default="{ item, index }: { item: MyType, index: number }"
></template>

Or, using the ListItem helper type:

html

<template #default="{ item, index }: ListItem<MyType>"></template>