在我关于 NativeScript-Vue 路由的上一篇文章中,我讨论了如何在 NativeScript-Vue 应用程序中进行基本的路由。我描述了通过手动路由功能提供的简单内置路由,以及它如何让你在应用程序的不同页面之间移动。
在本文中,我将介绍一种不同的技术。我将介绍一个类似选项卡的界面,其中某个导航 UI(想想屏幕底部的选项卡)将在其上方加载不同的组件,而不是更改整个页面(例如,从“列表”页面更改为“详情”页面)。
和以前一样,我要感谢Jen Looper 的帮助!
Vue 可以做的事情之一是使用动态组件。这是通过 :is
声明实现的。例如
<component :is="someComponent" />
在这个例子中,基本的 component
标签将被渲染为 someComponent
的值。你甚至可以动态切换它。如果 someComponent
指向 Cat
组件,但后来指向 Dog
,Vue 将自动处理更新新组件的显示。我写了一个例子,几个月前使用动态表单字段完成的。
这项技术也给了我们一种有趣的方式进行导航。如果我们把 <component>
标签看作我们的“视图”,那么我们就可以通过简单地交换 is
属性的当前值来“导航”。
让我们看一个实际应用的例子。
首先,我们的主“首页”组件
<template>
<Page class="page">
<ActionBar :title="currentComponent" class="action-bar" />
<GridLayout rows="2*, auto" columns="*, *, *">
<component v-for="component in viewsArray" v-show="component === currentComponent" :is="component"
row="0" col="0" colSpan="3"/>
<Button text='Info' @tap="currentComponent = 'CatInfo'" row="1" col="0" />
<Button text='Pic' @tap="currentComponent = 'CatPic'" row="1" col="1" />
<Button text='Log' @tap="currentComponent = 'CatLog'" row="1" col="2" />
</GridLayout>
</Page>
</template>
<script>
import CatInfo from './CatInfo';
import CatPic from './CatPic';
import CatLog from './CatLog';
export default {
data () {
return {
viewsArray: [ 'CatInfo', 'CatPic', 'CatLog' ],
currentComponent: 'CatInfo'
};
},
components: {
CatInfo, CatPic, CatLog
}
}
</script>
让我们从标记开始。首先,请注意 GridLayout
的使用。这里的想法是为我们的“视图”设置应用程序的顶部部分,为导航设置应用程序的底部部分。GridLayout
中的第一个元素是 component
标签。从技术上讲,多个标签,因为你可以看到那里使用了 v-for
。我们不想同时看到三个视图,所以这是如何工作的?首先要注意使用 v-show
来确保我们一次只看到一个。然后注意相同的位置信息(row
和 col
),这样组件基本上就会彼此堆叠。最后,底部三个按钮处理导航。
现在让我们看看代码。一组可能的视图在名为 viewsArray
的数组中定义。这就是绑定到上面 component
标签的内容。然后有一个简单的字符串值叫做 currentComponent
。如果你回到按钮那里,你会看到那里的逻辑只是改变了字符串的值。
最终的结果是,你可以点击每个按钮来交换当前可见的视图。虽然这些视图没什么特别,但这是 CatInfo
<template>
<Label text="cat info!" />
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
这里还有一个例子,CatPic
<template>
<Image src="https://placekitten.com/400/500" />
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
最后,应用程序运行时的屏幕截图
你可以在这个 NativeScript Playground 项目中看到整个应用程序,并在你的设备上测试它。有关这项技术的另一个例子,请查看 Jen Looper 的例子这里。
对于下一个例子,我们将做一些比以前更底层的事情。每个 NativeScript 应用程序都使用一个名为 Frame
的核心 UI 元素。Frame
是渲染你的 Page
组件的地方。你可能以前甚至没有注意到这一点。在默认的 NativeScript Vue 应用程序中,你的 app.js
文件将如下所示
import Vue from 'nativescript-vue';
import HelloWorld from './components/HelloWorld';
// Uncommment the following to see NativeScript-Vue output logs
// Vue.config.silent = false;
new Vue({
template: `
<Frame>
<HelloWorld />
</Frame>`,
components: {
HelloWorld
}
}).$start();
注意 template
属性。它定义了要由 Frame
标签包装的核心布局。HelloWorld
组件本身被包装在一个 Page
中。但是,你被允许修改此布局以创建更高级的布局和导航方案。例如,你可以拥有多个 frame,每个 frame 都有自己的页面,并使用导航来操作它们中的任何一个。每个 frame 将拥有自己的导航历史记录,你可以回到每个 frame 的前面或后面。
对于我们选项卡式应用程序的下一个版本,我们仍然要使用一个 frame,但我们将修改核心布局,以便在应用程序的第一个组件中设置 frame。
首先,这里是 app.js
文件
import Vue from 'nativescript-vue';
import Home from './components/Home';
// Uncommment the following to see NativeScript-Vue output logs
//Vue.config.silent = false;
new Vue({
render: h => h(Home)
}).$start();
注意,这里没有模板,而是直接渲染我们的主组件 Home
。现在让我们看看它。
<template>
<GridLayout rows="*, auto">
<ContentView row="0">
<Frame>
<CatInfo />
</Frame>
</ContentView>
<Nav row="1" />
</GridLayout>
</template>
<script>
import CatInfo from './CatInfo';
import Nav from './Nav';
export default {
data() {
return {};
},
components: {
CatInfo, Nav
}
};
</script>
和以前一样,我们希望最终在顶部有一个“视图”,在底部有一个导航栏。(说清楚一点,这是随意的。你的选项卡可以在顶部、右边,任何你想要的地方。)注意 ContentView
和 Frame
在网格顶部部分的使用。这将是渲染我们内容的地方。由于应用程序的第一个“页面”是硬编码的,它只是直接在那里输入。我们的导航现在被分解到它自己的组件 Nav
中
<template>
<GridLayout rows="auto" columns="*, *, *">
<Button text='Information' @tap="goTo('info')" row="1" col="0" />
<Button text='Picture' @tap="goTo('pic')" row="1" col="1" />
<Button text='Log' @tap="goTo('log')" row="1" col="2" />
</GridLayout>
</template>
<script>
import CatInfo from "./CatInfo";
import CatPic from "./CatPic";
import CatLog from "./CatLog";
export default {
data() {
return {
routes: {
info: CatInfo,
pic: CatPic,
log: CatLog
}
};
},
methods: {
goTo(s) {
this.$navigateTo(this.routes[s]);
}
}
};
</script>
和前面的例子一样,选项卡栏被定义为一组按钮。这次我们使用了一个方法 goTo
,并将要导航到的路由的名称传递给它。$navigateTo
方法用于处理加载我们的视图,由于我们的应用程序只有一个 Frame
标签,它将自动在其中加载组件。你可以使用 $navigateTo
的参数之一来指定一个 frame,如果你有多个 frame 的话。
和以前一样,每个页面几乎都是一样的,但是要注意,我们现在需要使用 Page
组件。这是 CatInfo
组件
<template>
<Page class="page">
<ActionBar title="Cat Information" />
<Label text="Information about the cat. Lorem ipsum meow." />
</Page>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
这是 CatPic
组件
<template>
<Page class="page">
<ActionBar title="Cat Picture" />
<Image src="https://placekitten.com/400/500" />
</Page>
</template>
<script>
export default {
data() {
return {};
}
};
</script>
和以前一样,你可以在这个 NativeScript Playground 项目中看到整个应用程序。此外,你还可以看到 Jen Looper 的更酷的例子这里。我特别喜欢她的例子的一点是,将“路由”进一步分解,使导航组件更加灵活。
我希望这些例子(以及上一篇文章中的例子)可以帮助你构建更强大的 NativeScript-Vue 应用程序。
如果你想要一个更高级的例子,你应该查看nativescript-vue-navigator 插件。它提供的体验更接近于“传统”的 Vue 路由,更容易上手。(和以前一样,Jen 有一个很好的例子来演示它的实际应用!)