Vue 路由

总是需要分发路由的,不然难道让用户在同一个路径下反复横跳?


本文将结合 官方文档myzone 项目代码 进行介绍

但是只是立即上手的方法,并不包含一些高级技法或者底层实现,所以还是以项目代码为主(

安装

可以通过 npm 安装 vue-router

1
npm install vue-router

如果在一个模块化工程中使用,需要显式引用

1
2
3
4
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

不仅是 /router/index.js 这个配置文件要引用,main.js 也是要引用

配置

路由规则

首先要指明什么路由指向什么组件

myzone 中采用下例路由规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import Vue from 'vue'
import Router from 'vue-router'
import login from '@/components/others/login'
import verify from '@/components/others/verify'
import index from '@/components/others/index'
import userInfo from '@/components/others/userInfo'
import message from '@/components/message/message'
import messageView from '@/components/message/messageView'

Vue.use(Router)

export default new Router({
mode: 'history',
routes: [
{
path: '*/verify',
name: 'verify',
components: {
verify: verify
}
},
{
path: '/login',
name: 'login',
components: {
login: login
}
},
{
path: '/',
name: 'index',
component: index
},
{
path: '/user/info',
name: 'userInfo',
component: userInfo
},
{
path: '/message',
name: 'message',
component: message
},
{
path: '/message/:messageId',
name: 'messageView',
component: messageView
}
]
})

对于每个项,通过 name 属性指出该路由规则的名称,通过 path 属性指明当是何种路径时触发该路由,并通过 component 属性指示路由标的是哪个组件

在本例中使用了通配符 * 表示匹配以 verify 结尾的任意路径,以及通配符 : 表示匹配任意数字

还可以使用嵌套路由以降低耦合度,不过 myzone 比较简单,所以没有这么做

写好路由规则后,配置一下 main.js,就可以使用了

1
2
3
4
5
import router from './router/index'
new Vue({
router,
...
})

路由出口

在 myzone 中,为 app.vue 这个页面主体,指定了如下 template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
<div id="app">
<router-view v-if="!this.$store.state.isLogin" name="login"/>
<router-view v-if="!this.$store.state.isLogin" name="register"/>
<router-view v-if="this.$route.path.endsWith('verify')" name="verify"/>
<div v-if="this.$store.state.isLogin">
<sideBar id="sideBar" v-show="this.$store.state.isSideBar"></sideBar>
<div class="mainBody">
<sideHeader class="sideHeader" v-if="this.$store.state.isLogin"></sideHeader>
<router-view class="mainContent" v-if="this.$store.state.isLogin && this.isRouterAlive" name="default"/>
<sideFooter class="sideFooter" v-if="this.$store.state.isLogin"></sideFooter>
</div>
</div>
</div>
</template>

实质上,主要使用 router-view 标签指示路由出口

显然,router-view 标签需要一个 name 参数来指示传递给该出口的是哪个路由

本例中通过 v-if 来控制用户登录与否时看到的页面情况

配置好路由出口后,还要配置路由的入口

路由入口

在命名路由(具有 name 属性的路由)情况下,可以使用 router-link 标签实现路由跳转,其功能约等于 a 标签

如上例,要跳转到 /message/123 页面下的话,可以在模板中写入

1
<router-link :to="{ name: 'messageView', params: { messageId: 123 }}">message</router-link>

为该标签绑定 to 属性以实现路由目标的指定

也可以在模板代码中实现跳转

1
$router.push({ name: 'messageView', params: { messageId: 123 }})

或者手动写入路径

1
$router.push('/message/123')

在非模板位置,记得写 this

模式

一般有三种模式,各有特点

  1. memory
  2. hash
  3. history

memory 是基于 localstorage 的本地存储,换一台机器就无法同步正在浏览的页面

hash 是基于 # 符号进行的分片,所有内容都是在用户端进行的变化,不会传递给服务器,同时也不能进行前进和后退

history 可以没有 # 号,基于访问路径进行索引,是常见的模式,可以前进和后退,但是所有请求都会到达服务器(指 nginx 或 apache),请确保服务器已经正确配置

在 myzone 中采用了 history 模式

懒加载

只需要改变 import 时的动作,其余什么都不需要改变

例如,要加载 /user/info 时,可以写成如下形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const userInfo = () => import('@/components/others/userInfo')

export default new Router({
mode: 'history',
routes: [
{
path: '/user/info',
name: 'userInfo',
component: userInfo
}
]
})

感谢阅读

--It's the end.Thanks for your read.--