Skip to content

Upgrade Guide ​

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:

  • Use createApp(Home) instead of new Vue().
  • The root <Frame> component should now be inside Home.vue (depending on your frame/navigation setup), not in the createApp function.

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 { $navigateTo, $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>

Released under the MIT License.