The easiest way to implement routing in NativeScript-Vue is to use any of the following convenience functions:
For more complex navigation scenarios, you can use multiple <Frame>
components and a navigation-specific component:
$navigateTo(Component, options)
You can call $navigateTo
in the view or in a method.
In the Master
component, use a data
property to expose the Detail
component. Invoke $navigateTo(<propertyName>)
in the view directly.
import Vue from 'nativescript-vue';
const Master = {
template: `
<Page>
<ActionBar title="Master" />
<StackLayout>
<Button text="To Details directly" @tap="$navigateTo(detailPage)" />
</StackLayout>
</Page>
`,
data() {
return {
detailPage: Detail
}
}
};
const Detail = {
template: `
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Label text="Details.." />
</StackLayout>
</Page>
`
};
new Vue({
render: h => h('frame', [h(Master)])
}).$start()
Bind a button to a method and use this.$navigateTo(Detail)
to navigate to the Detail
component.
const Master = {
template: `
<Page>
<ActionBar title="Master" />
<StackLayout>
<Button text="To Details via method" @tap="goToDetailPage" />
</StackLayout>
</Page>
`,
methods: {
goToDetailPage() {
this.$navigateTo(Detail);
}
}
};
const Detail = {
template: `
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Label text="Details.." />
</StackLayout>
</Page>
`
};
$navigateTo
accepts a second options
parameter. You can use the parameter to:
props
object to be used when instantiating the target componentFor example:
this.$navigateTo(Detail, {
transition: {},
transitioniOS: {},
transitionAndroid: {},
props: {
foo: 'bar',
}
});
For more information about the options that you can pass, see NavigationEntry
.
Each <Frame>
element has its own navigation stack. If you are using multiple frames, you may want to specify in which frame the navigation will occur. For example, having a button in the side bar that changes the page in the main area. You can do this by adding the frame
option:
this.$navigateTo(SomeComp, {
frame: '<id, or ref, or instance>'
});
The value for the frame
option can be one of the following:
id
of the <Frame>
component (for example: <Frame id="main-frame">
)ref
for the <Frame>
(for example: <Frame ref="mainFrame">
)<Frame>
instance itself$navigateBack(options, backstackEntry = null)
In the Detail
component, add a button that triggers the globally exposed $navigateBack
function.
const Detail = {
template: `
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Button text="Back to Master" @tap="$navigateBack" />
</StackLayout>
</Page>
`
};
Use $showModal
to show the Detail
page modally. This function behaves similarly to $navigateTo
.
You can call $showModal
in the view or in a method. To close the modal, call $modal.close
.
In the Master
component, use a data
property to expose the Detail
component. Invoke $showModal(<propertyName>)
in the view directly.
import Vue from 'nativescript-vue';
const Master = {
template: `
<Page>
<ActionBar title="Master" />
<StackLayout>
<Button text="To Details directly" @tap="$showModal(detailPage)" />
</StackLayout>
</Page>
`,
data() {
return {
detailPage: Detail
}
}
};
const Detail = {
template: `
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Button @tap="$modal.close" text="Close" />
</StackLayout>
</Page>
`
};
new Vue({
render: h => h('frame', [h(Master)])
}).$start()
Bind a button to a method and use this.$showModal(Detail)
to navigate to the Detail
component.
const Master = {
template: `
<Page>
<ActionBar title="Master" />
<StackLayout>
<Button text="Show Details modally" @tap="showDetailPageModally" />
</StackLayout>
</Page>
`,
methods: {
showDetailPageModally() {
this.$showModal(Detail);
}
}
};
const Detail = {
template: `
<Frame>
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Button @tap="$modal.close" text="Close" />
</StackLayout>
</Page>
</Frame>
`
};
Note: We've wrapped the Detail page in a <Frame>
element, which allows us to show the <ActionBar>
as well as navigate further within the modal.
$showModal
accepts a second parameter. You can use the parameter to pass in a props
object to the target component. For example:
this.$showModal(Detail, { props: { id: 14 }});
You also need to update the Detail
component to be able to accept the id
prop. You can do this by defining a props
option inside the component:
const Detail = {
props: ['id'],
template: `
<Page>
<ActionBar title="Detail"/>
<StackLayout>
<Label :text="id" />
<Button @tap="$modal.close" text="Close" />
</StackLayout>
</Page>
`,
};
The prop is now accessible throughout the component with this.id
.
For more information about props, see the official Vue documentation
This option only takes effect on Android, as iOS modals are always fullscreen.
this.$showModal(Detail, { fullscreen: true, props: { id: 14 }});
When calling $showModal
, a promise is returned which resolves with any data passed to the $modal.close
function.
In the following example, closing the modal outputs 'Foo' in the console.
// ... inside Master
this.$showModal(Detail).then(data => console.log(data));
<!-- inside Detail -->
<Button @tap="$modal.close('Foo')" text="Close" />
The <BottomNavigation>
and <Tabs>
components enable the user to arbitrarily navigate between several UI containers at the same level. A key feature of these components is that they keep the state of the containers that are not visible. This means that when the user comes back to a previous tab, the data, scroll position and navigation state should be like they left them.
The examples below use the <BottomNavigation>
component. You can use the same markup for the <Tabs>
component. Just replace the <BottomNavigation>
tags with <Tabs>
tags.
The <BottomNavigation>
container provides its lateral navigation logic automatically by providing the user with tabs which they can select. To set up a <BottomNavigation>
you need to simply declare the UI of each container (within a <TabContentItem>
) and the title and icon you want to be shown in its representing tab (within a <TabStripItem>
). Each separate UI container is represented by a <TabContentItem>
. A <TabContentItem>
can have one root component. As with other containers, you can enable forward and backward navigation inside each <TabContentItem>
by embedding a <Frame>
in it.
import Vue from 'nativescript-vue';
import Items from './components/Items.vue';
import Browse from './components/Browse.vue';
import Search from './components/Search.vue';
const App = {
components: {
Items,
Browse,
Search
},
template: `
<BottomNavigation>
<TabStrip>
<TabStripItem>
<Label text="Home"></Label>
</TabStripItem>
<TabStripItem>
<Label text="Browse"></Label>
</TabStripItem>
<TabStripItem>
<Label text="Search"></Label>
</TabStripItem>
</TabStrip>
<TabContentItem>
<Frame id="homeTabFrame">
<Items />
</Frame>
</TabContentItem>
<TabContentItem>
<Frame id="browseTabFrame">
<Browse />
</Frame>
</TabContentItem>
<TabContentItem>
<Frame id="searchTabFrame">
<Search />
</Frame>
</TabContentItem>
</BottomNavigation>
`
};
new Vue({
render: h => h(App)
}).$start();
To create a new application utilizing the <BottomNavigation>
component run:
tns create my-app-name --template tns-template-tab-navigation-vue
The <RadSideDrawer>
component enables the user to open a hidden view, i.e. drawer, containing navigation controls, or settings from the sides of the screen. For more information about it, read the dedicated article.
To create a new application utilizing the <RadSideDrawer>
component run:
tns create my-app-name --template tns-template-drawer-navigation-vue