返回博客首页
← 所有文章

使用 NativeScript-Vue 实现路由:第一集

2019 年 7 月 23 日 — 作者:Raymond Camden

作为 NativeScript-Vue 的新手,当你在 导航文档 中看到这个时,你可能会有点担心

Vue Router (Unsupported)

Vue Router...不支持!?!?这意味着什么?我们永远只能用一个视图锁定在 Vue 应用上吗?为什么这样,我们做了什么让这样的诅咒降临到我们头上?

幸运的是,情况并没有你想象的那么糟糕。正如你可能猜到的那样,上面的 "手动路由" 选项会引导你讨论如何在没有我们熟悉的 Vue Router 的情况下进行路由。不仅如此,你还可以应用其他一些替代方法。

在本文中,我将介绍一些 Vue 和 NativeScript 路由的示例。你将拥有完整的示例,可以立即将其用于自己的项目。在我继续之前,我要感谢 Jen Looper 在本文中提供的帮助。如果你还没有浏览过令人难以置信的 Vue Vixens 项目,你应该尽快这样做!

像我们的祖先一样导航

处理导航的第一个也是最简单的方法,就像我们的祖父母一样。上坡,来回,在雪地里。好吧,也许没有那么糟糕。手动路由的 文档 讨论了两种不同的方法。(第三种方法也进行了讨论,它处理模态。我个人认为这不是 "导航",但请注意,它是一个选项。)

第一个,$navigateTo,讨论了如何在应用程序中从一个视图移动到另一个视图。最简单的形式,你只需指定要导航到的组件,但你也可以传递多个参数,详细说明诸如过渡以及你想要沿途发送的数据之类的事情。

第二个,$navigateBack,负责将你返回到最后一个视图。简单而方便。

鉴于这两种方法,完整的示例如何呢?让我们从一个包含两个视图(路由)的应用程序开始。第一个组件将链接到第二个,第二个组件将链接回第一个。我在 NativeScript Playground 上创建了一个新的 NativeScript Vue 应用程序。这是初始组件

<template>
    <Page class="page">
        <ActionBar title="Home" class="action-bar" />
        <StackLayout>
            <Button @tap="goToSecond" text="Go to Second"></Button>
        </StackLayout>
    </Page>
</template>

<script>
import Second from './Second';

export default {
    data () {
        return {
        };
    },
    methods: {
        goToSecond() {
            this.$navigateTo(Second)
        }
    }
}
</script>

<style scoped>
</style>

布局包含一个 UI 项目,一个带有 tap 事件的按钮,该事件执行 goToSecond。该方法随后使用 this.$navigateTo 将用户发送到下一个组件。让我们看看它。

<template>
    <Page class="page">
        <ActionBar title="Second" class="action-bar" />
        <StackLayout>
            <Button @tap="this.$navigateBack" text="Go Back"></Button>
        </StackLayout>
    </Page>
</template>

<script>
    export default {
        data() {
            return {};
        }
    };
</script>

<style>
</style>

这个也只有一个 UI 项目,一个按钮,但请注意,我没有为 tap 事件定义方法,而是直接在其中内联了它。这在第一个组件中也可以使用。你可以在 这个 NativeScript Playground 项目 中自己测试它。

使用样式(和数据)进行导航

使用 $navigateTo 时,你可以传递第二个参数,它允许你指定过渡效果以及要发送到第二个视图的 props(数据)。你可以用这个参数做更多事情,可以在 NavigationEntry 的参考指南中找到完整文档。这是一个使用 fade 过渡的简单示例。

this.$navigateTo(Second, {
    transition: {
        name:'fade',
        duration: 200
    }
})

传递数据是通过 props 键完成的

this.$navigateTo(Second, {
    transition: {
        name:'fade',
        duration: 200
    },
    props: {
        something: 1, 
        somethingElse: 'cat'
    }
})

使用 props 时,这些值最终会作为 props 传递到下一页。因此,就像在任何 Vue 组件中一样,如果你定义了一个 props 数组,props: ['something', 'somethingElse'],那么你就可以使用传入的代码简单地

Hello, I like to eat pie and {{ something }} along with {{ somethingElse }}.

通过完整的示例,这将更有意义。让我们构建一个简单的两页应用程序,它利用了 Star Wars API。第一页将命中 API 获取电影列表。我们将把它显示为电影标题列表。在 tap 上,我们将导航到一个新页面。API 同时返回所有电影数据,因此我们可以将电影数据作为 props 值传递给下一个视图。

让我们从第一页开始,一个名为 Films.vue 的组件

<template>
    <Page class="page">
        <ActionBar title="Movies" class="action-bar" />
        <ScrollView height="100%">
            <ListView for="movie in movies" @itemTap="loadMovie">
                <v-template>
                    <Label :text="movie.title" padding="20" />
                </v-template>
            </ListView>
        </ScrollView>
    </Page>
</template>

<script>
import Film from './Film';

export default {
    methods: {
        loadMovie(e) {
            this.$navigateTo(Film, {
                transition: {
                    name: 'fade',
                    duration: 1000
                },
                props: {
                    film: e.item
                }
            });
        }
    },
    data() {
        return {
            movies: []
        };
    },
    created() {
        fetch("https://swapi.co/api/films/")
        .then(res => res.json())
        .then(res => {
            this.movies = res.results;
        })
        .catch(e => {
            console.log('Error calling API', e);
        });
    }
};
</script>

布局相当简单,只是一个 ListView 组件。我将它引入到一个 movies 数组中,该数组将在稍后加载。tap 事件将触发 loadMovie,我们将在那里进行导航。

在 JavaScript 中,我使用 created 事件来调用 Star Wars API。我解析 JSON,然后将结果分配给 movies 数组。

loadMovie 方法使用 this.$navigate 来指定我要去哪里(Film 组件),定义一个过渡,以及我的 props 值,在本例中只有一个,film。现在让我们看看 Film 组件

<template>
    <Page class="page">
        <ActionBar :title="film.title" class="action-bar" />
        <StackLayout height="100%">
            <Label :text="film.opening_crawl" textWrap="true" />
            <Button @tap="this.$navigateBack" text="Back" />
        </StackLayout>
    </Page>
</template>

<script>
export default {
    props: ["film"],
    data() {
        return {};
    }
};
</script>

在这个组件中,我只做了定义 film 作为 props。由于导航会将它传递进来,我就可以在组件中使用电影数据。Star Wars API 返回了许多关于电影的信息,但为了简单起见,我只显示开场字幕。

In case you don't remember what the 'crawl' is...

你可以在 这个 NativeScript Playground 项目 中自己试用它。

下一步?

在本文中,我介绍了使用 NativeScript 和 Vue 进行导航的基础知识。在我的下一篇文章中,我将通过两个更复杂的示例来提升它:选项卡式界面以及使用来自 NativeScript 社区的类似 "Vue Router" 的资源。