这篇教程我们将从Vue里最基础的路由/导航开始讲起,然后再看看通过Vue构建的Ionic应用如何导航。
在Vue里引入Ionic的组件(或者任何其他东西)是非常简单的,就像你在Angular中做的一样,只需要把他们注入模板里,不过当我们想在两个页面之间导航时稍微变复杂了一点。在Angular里,我们只是用ionic-angular库提供的NavController服务,但是在Vue里我们将依赖于Vue自己的路由。
备注:Ionic4(允许我们脱离Angular使用Ionic)还处于早期版本——记住我们做的这些都是带有实验性质的。
Vue导航
就像我在上一篇文章里说的,Vue比Angular更加轻量化,组织性没有那么严密。Angular提供了所有开箱即用的东西,但是在Vue里你需要自己填补空白。
导航就是你需要填补的空白的一部分,尽管你可以在Vue里使用任何路由,Vue还是提供了一个默认的路由,你可以在项目创建的时候设置它。
如果你选择使用Vue router,它会自动设置好项目的路由机制。如果打开src/App.vue你会发现router-view标签:
<template>
<div id="app">
<img src="./assets/logo.png">
<router-view/>
</div>
</template
这和Ionic的ion-nav组件很相似,作为不同页面之间导航的container,需要显示的视图就会显示在router-view标签的位置。
在你的项目里有一个router文件夹,看看router/index.js文件:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
component: HelloWorld
}
]
})
这里定义了这个应用所有的路由。如果你过去一直使用Ionic(不怎么熟悉Angular)那你可能对这种抽象路由的定义不是很熟,不过这种概念其实很简单。我们需要提供一个path 值作为这个页面的地址URL,还要提供一个组件作为这个页面用到的组件。我们可以像这样添加很多的路由对象到routes数组里。
如果你想导航到一个页面,只需要在router-link标签里这样使用:
<router-link to="/detail">Go to the Detail Page</router-link>
或者如果你想使用一个方法来导航到另一个页面:
methods: {
goToDetail () {
this.$router.push('detail')
}
}
然后在你的模板这样使用这个方法:
<button @click="goToDetail">Go to the Detail Page</button>
现在我们看一眼src/main.js文件,你会发现router也被设置好了:
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
这是当我们使用CLI时自动设置好的,你没什么需要担心的。不过当初始化一个Vue应用时,确保这里已经引入了它是很重要的。
Ionic/Vue应用导航
既然我们已经过了一遍基础,现在来看看如何在使用Vue构建的Ionic应用里面导航。为了使Ionic的web components可以在我们的Vue应用使用,我们需要在index.html引入下面这行代码:
<script src="https://unpkg.com/@ionic/core@0.0.2-20/dist/ionic.js"></script>
记住这里面包含的是一个Ionic4的早期版本,仅此一步基本可以让我们运行Ionic,不过还有几步:
如果你试着在手机设备上看这个应用,它的尺寸不太对。为了使应用在手机上正确的显示,我们需要使用meta标签。我们可以在一个普通的Ionic/Angular应用里复制过来:
添加下面的meta标签到index.html:
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
因为我们在使用web components,我们其实是在试图添加一些普通html不存在的标签到我们的Vue应用,而且也没有被定义为Vue组件。如果我们试着在Vue里使用Ionic组件,运行之后会看到这个错误:
[Vue warn]: Unknown custom element: <ion-app>
既然Vue不认识这些自定义元素,我们需要在src/main.js里进行如下设置:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
Vue.config.ignoredElements = [
'ion-app',
'ion-header',
'ion-navbar',
'ion-title',
'ion-content',
'ion-button'
];
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
你需要把你想使用的Ionic组件添加到ignoredElements 数组——你不需要引入你没有使用的Ionic组件。
现在我们可以在Vue组件里使用Ionic组件了,让我们把已经存在的HelloWorld组件Ionic化吧。
修改src/components/HelloWorld.vue如下:
<template>
<ion-app>
<ion-header>
<ion-navbar>
<ion-title>Ionic</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-button @click="goToDetail">Hello</ion-button>
</ion-content>
</ion-app>
</template>
<script> export default { name: 'HelloWorld', data () { return { msg: 'Welcome to Your Vue.js App' } }, methods: { goToDetail () { this.$router.push('detail') } } } </script>
<style scoped> </style>
现在我们只是使用Ionic组件创建普通的模板。我们使用 @click来触发goToDetail方法。这会进入detail页面,不过我们还没创建这个页面。你可以看到,这并不是一点也不像Ionic/Angular。我们只是使用@click代替(click),使用 $router代替NavController的push方法。虽然看起来有一点不同,但是基本的概念都是相同的。
在Vue里创建一个新的Ionic页面
我们试着push到detail页面,不过我们还没创建这个页面,而且还没为它设置路由。我们现在来做这个:
创建src/components/Detail.vue文件:
<template>
<ion-app>
<ion-header>
<ion-navbar>
<ion-title>Ionic</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p><router-link to="/">Go home</router-link></p>
</ion-content>
</ion-app>
</template>
<script> export default { name: 'Detail', data () { return { msg: 'Welcome to Your Vue.js App' } } } </script>
<style scoped> </style>
这个组件和HelloWorld组件非常相似,只是更简单了。这次我们使用router-link标签来导航返回home页面。在Ionic应用里一般不会像这样使用一个文本链接进行导航,不过我只是展示一下这种方式的用法:
组件定义好了,我们来为它创建路由:
如下修改router/index.js的内容:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Detail from '@/components/Detail'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
component: HelloWorld
},
{
path: '/detail',
component: Detail
}
]
})
我们引入刚刚创建的Detail组件然后设置它的路由。现在我们可以在Vue的两个Ionic页面之间*切换了。
页面过渡动画
我们现在可以在两个Ionic页面之间切换,不过运行代码你会注意到页面之间的过渡太过突兀。这可能有点不友好, 因为在两个页面之间转换时通常会出现各种类型的页面转换动画。
Angular里使用NavController自动帮我们处理好了这件事,不过现在我们不能用那个,怎么办呢?
幸运的是,Vue对像这样的过渡动画有着非常好的支持。为了设置一个全局的过渡动画,我们使用Vue文档里的一个例子。
如下修改src/App.vue:
<template>
<div id="app">
<transition name="slide-fade">
<router-view/>
</transition>
</div>
</template>
<script> export default { name: 'app' } </script>
<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } /* Enter and leave animations can use different */ /* durations and timing functions. */ .slide-fade-enter-active { transition: all .3s ease; } .slide-fade-leave-active { transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); } .slide-fade-enter, .slide-fade-leave-to /* .slide-fade-leave-active below version 2.1.8 */ { transform: translateX(10px); opacity: 0; } </style>
我们将router-view放在了transition(当它们离开或者进入时可以产生动画效果的组件)标签里面。在这个组件的style标签里,我们给它设置了一个叫slide-fade的动画。这样修改之后,你在切换两个页面会注意到现在有了动画过渡效果。
虽然这没有Angular的Ionic服务的默认效果好,不过只要你喜欢你可以设置更复杂的动画——只是一个关于定义合适动画效果的问题。如果你愿意,你也可以给特定的标签设置特定的动画,而不是使用一个全局的动画。更多的你可以看看这个。
总结
Ionic/Angular和Ionic/Vue导航最主要的不同点就是在Vue里我们需要定义路由,因为不依赖于NavController我们需要自己处理页面过渡动画。除了一些细微的差别, 基本概念与Ionic/Angular上的导航差不多。