使用Vue构建Ionic混合APP系列教程(二):导航

时间:2022-08-17 20:46:16

这篇教程我们将从Vue里最基础的路由/导航开始讲起,然后再看看通过Vue构建的Ionic应用如何导航。

在Vue里引入Ionic的组件(或者任何其他东西)是非常简单的,就像你在Angular中做的一样,只需要把他们注入模板里,不过当我们想在两个页面之间导航时稍微变复杂了一点。在Angular里,我们只是用ionic-angular库提供的NavController服务,但是在Vue里我们将依赖于Vue自己的路由。

备注:Ionic4(允许我们脱离Angular使用Ionic)还处于早期版本——记住我们做的这些都是带有实验性质的。

Vue导航

就像我在上一篇文章里说的,Vue比Angular更加轻量化,组织性没有那么严密。Angular提供了所有开箱即用的东西,但是在Vue里你需要自己填补空白。

导航就是你需要填补的空白的一部分,尽管你可以在Vue里使用任何路由,Vue还是提供了一个默认的路由,你可以在项目创建的时候设置它。

使用Vue构建Ionic混合APP系列教程(二):导航

如果你选择使用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上的导航差不多。