Vue Router学习(一)

最近在尝试用Vue.js来重构我之前用react写的豆瓣项目了,感觉vue-router这块的内容还是挺多的,在项目的重构中也看了官方文档跟上网其他人的博客,也决定自己总结一下相关的一些内容,把自己在项目中遇到的点做一些整理。这个估计一次性也是说不完的,所以也分几篇来整理了。

以下使用的一些示例代码是来源于我的豆瓣项目:https://github.com/listentolife/Vue-doubanPocket

这里先整理动态路由跟嵌套路由。

基础路由

首先,vue-router是vue.js的官方路由管理器,功能在官方文档中有列表介绍,我会根据开发中对vue-router使用的程度一点点整理。

最基础的路由使用,官方给出了完整的操作,包括JavaScript的五步操作:引入调用vue-router,定义组件,定义路由,创建配置router实例,创建和挂载根实例。

JavaScript操作

实际操作中,我在项目的src目录下会创建一个router目录,在这里完成上面JavaScript的前四步操作:

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
// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Book from 'components/book/book'
import Movie from 'components/movie/movie'

// 注册Router
Vue.use(Router)

export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
redirect: '/book'
},
{
path: '/book',
name: 'book',
component: Book
},
{
path: '/movie',
name: 'movie',
component: Movie
}
]
})

然后在根实例上挂载:

1
2
3
4
5
6
7
8
9
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'

new Vue({
router,
render: h => h(App)
}).$mount('#app')

router组件操作

然后就可以使用<router-link>导航组件跟<router-view>组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// components/tag.vue
/* 在router-link导航,
* tag指定组件会被渲染成什么标签,默认为a标签
* to传入的是指定的链接,也可以是一个对象,这个后面再细说
*/
<router-link class="tab-item" tag="div" to="/book">
<span class="tab-link">图书</span>
</router-link>
<router-link class="tab-item" tag="div" to="/movie">
<span class="tab-link">电影</span>
</router-link>

// 路由匹配到的组件会渲染在这里
<router-view></router-view>

this.$routerthis.$route

这样就可以完成最简单的路由。“我们可以在任何组件内通过this.$router访问路由器,也可以通过this.$route访问当前路由”

上面这段引号的话是需要注意的。通过this.$router是访问路由器,通过this.$route是访问当前路由

一开始我也不是很明白,就在项目中写了一段console.log,尝试打印一下这两个:

this.$router & this.route

这样看就比较明白了:this.$router指向的是router目录中创建的路由实例,this.$route指向的是当前渲染的路由对象。

通过this.$routethis.$router,我们有一些常用的方法可以调用,这里就属于编程式导航中会提及的内容,等后面再整理了。

动态路由

上面的例子是比较简单的路由实现,但实际上很多时候是没办法把路由路径写死的,比较用户页面,比如我的项目中每个图书页面都是一样的,但是图书是各不相同的。这个时候就需要用到动态路由来实现。

实现动态路由,需要以下几步(基于上面的例子):

1
2
3
4
5
6
7
// router/index.js
// 先在路由器上配置路由
{
path: '/musicDetail/:id',
name: 'music-item',
component: MusicItem
}

/musicDetail/:id这个路径包含了一个路径参数id,前面使用:标记。这个路径参数会被设置到this.$route.params中,可以被组件使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
// music.vue
// 使用动态路由,就需要用对象来传值给to
// 路由渲染后,地址上也是显示/musicDetail/(music.title)
<router-link
class="music-list"
tag="li"
:to="{name:'music-item',params:{id:music.title,music:music}}"
v-for="music in musics"
:key="music.title"
>...</router-link>

// 路由匹配到的组件会渲染在这里
<router-view></router-view>

在组件内,就可以利用this.$route.params可以获得父组件传入的值。由于在路由配置时路径参数只有id,所以只有id会显示在地址上,其他值不会显示在地址上,可以传入很多数据。

有几个地方需要留意的:

  1. 一个路由可以设置多段路径参数,但是一定要一一匹配上;
  2. 使用动态路由,匹配同一动态路径的路由之间导航,组件实例会被复用,组件的声明钩子将不会再被调用。可以使用watch或导航守卫响应路由变化;
  3. 多个路由同时匹配同一路径时,最先定义的优先级越高。

嵌套路由

嵌套路由就是在路由内再嵌套路由组件,通过路由做跳转,跳转前后父路由组件不受影响。比如根路径‘/’下路由导航到‘/book’,渲染book组件,在book组件内有子路由‘/book/detail/:id’,路由跳转时,book组件内<router-view>之外不受影响。

子路由配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
// router/index.js
// 在'/book'路由下配置子路由
{
path: '/book',
name: 'book',
component: Book,
children: [{
// 当/book/:id匹配成功,就会在book组件内的<router-view>中渲染bookItem组件
path: ':id',
name: 'book-item',
component: BookItem
}]
},

子路由导航与出口:

1
2
3
4
5
6
7
8
9
10
11
12
13
// book.vue
// 写法跟动态路由中的差不多
<router-link
class="book-list"
tag="li"
:to="{name:'book-item',params:{id:book.title,book:book}}"
v-for="book in books"
:key="book.title"
>...</router-link>

// 路由匹配到的组件会渲染在这里
// 注意,这个<router-view>是写在book组件中的
<router-view></router-view>

嵌套路由也有需要注意的:上面子路由配置中,path的值是 ‘:id’ ,不是 ‘/:id’ 。如果路径前有/斜杠,则嵌套路径指向根路径上的。

以上就是Vue Router关于动态路由跟嵌套路由的内容整理。