vue router
前面我们知道怎么创建一个vue项目,今天我们就来看一下vue中的vue router。
它是 Vue.js 官方的路由管理器 并且与 Vue.js 的核心深度集成,可以让构建单页面应用变得易如反掌。包含的功能有:
1. 嵌套的路由/视图表
2. 模块化的、基于组件的路由配置
3. 路由参数、查询、通配符
4. 基于 Vue.js 过渡系统的视图过渡效果
5. 细粒度的导航控制
6. 带有自动**的 CSS class 的链接
7. HTML5 历史模式或 hash 模式,在 IE9 中自动降级
8. 自定义的滚动条行为
我们拿vue-cli生成的项目来说,其中vue-router的简单配置如下:
import Vue from 'vue'
import Router from 'vue-router'
// 导入需要配置路由的组件
import HomePage from '@/components/HomePage'
// 注册使用vue router
Vue.use(Router)
export default new Router({
routes: [
{
path: '/', //当前匹配的路径
name: 'HomePage', // 映射的组件名称
component: HomePage //映射的组件
}
]
})
这里我给代码进行了简单的说明。
顺便说一下router-view:
<router-view> 组件是一个 functional 组件,渲染路径匹配到的视图组件。<router-view> 渲染的组件还可以内嵌自己的 <router-view>,根据嵌套路径,渲染嵌套组件。
其他属性 (非 router-view 使用的属性) 都直接传给渲染的组件, 很多时候,每个路由的数据都是包含在路由参数中。
因为它也是个组件,所以可以配合 <transition> 和 <keep-alive> 使用。如果两个结合一起用,要确保在内层使用 <keep-alive>:
<transition>
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
我们来看下路由的基本使用,那么在一个vue项目里面该怎么使用路由跳转呢?
在vue中,vue-router有两种跳转方式:
-
使用内置的router-link组件
然后我们运行一下程序:
我们可以看到其实router-link最终会被渲染为a标签,这里我们一般只需要关注props属性to就好了,to对应的是跳转的路径,可以进行动态绑定 -
使用router的实例方法
router的实例方法我们最常用到的有以下几个:
router.push
router.replace
router.go
router.back
router.forward
函数签名:
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
router.back()
router.forward()
具体的大家可查阅官方文档。
这里我们演示一下使用push方法进行路由跳转的代码:
HomePage.vue:
<template>
<div>
<div @click="goto" style="color: skyblue;cursor: pointer;">点击我可以跳转哦</div>
<button @click="forward" style="margin-top: 20px;">forward</button>
</div>
</template>
<script>
export default {
name: 'HomePage',
data() {
return {};
},
methods: {
goto() {
this.$router.push('/about');
},
forward() {
this.$router.forward();
}
}
};
</script>
<style scoped>
</style>
About.vue:
<template>
<div>
<p>本课程是关于vue-router的基本知识,所有知识点大家都可以在官方文档中找到,提前祝大家即将来到的新年快乐!</p>
<button @click="back" style="margin-top: 20px;">back</button>
<button @click="forward" style="margin-top: 20px;">forward</button>
</div>
</template>
<script>
export default {
name: 'About',
methods: {
back() {
this.$router.back();
},
forward() {
this.$router.forward();
}
}
};
</script>
<style>
</style>
运行效果:
接下来我们在看一个场景,我们的网站有很多的用户,当点击这个用户的时候,我们需要一个页面去展示这个用户的个人信息。我们会单独抽取一个组件叫Users,对于所有 ID 各不相同的用户,都要使用这个组件来渲染,此时我们就需要通过路由进行传参来达到我们的目的。
router-link传递参数的方式:
<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>
<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>
<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<!-- 带查询参数,下面的结果为 /register?plan=private -->
<router-link :to="{ path: 'register', query: { plan: 'private' }}">Register</router-link>
在上面的基础上创建Users组件,这里模拟一些用户数据。
<template>
<div style="border: 1px dashed skyblue;">
<div>
<span>{{activeUser.username}}</span>
<span>{{activeUser.visitDate}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'Users',
data() {
return {
userList: [
{
id: 0,
username: 'name0',
visitDate: Date.now()
},
{
id: 1,
username: 'name1',
visitDate: Date.now()
},
{
id: 2,
username: 'name2',
visitDate: Date.now()
},
{
id: 3,
username: 'name3',
visitDate: Date.now()
}
],
activeUser: {}
};
},
mounted() {
console.log(this.$route);
this.activeUser = this.userList.filter(user => {
console.log(this.$route.params.id, user.id);
if (this.$route.params.id == user.id) {
return user;
}
})[0];
console.log(this.activeUser);
}
};
</script>
<style>
</style>
然后配置路由:
{
path: '/users/:id',
name: 'Users',
component: Users
},
其中路由配置的是/users/:id,:id
表示我们的路由会传递一个参数,名称为id。
现在我们修改HomePage页面:
<template>
<div>
<p>
<span>用户id:</span>
<input v-model="id" />
</p>
<router-link :to="'/users/'+id">查看用户id为{{id}}的个人信息</router-link>
</div>
</template>
<script>
export default {
name: 'HomePage',
data() {
return {
id: 0
};
},
methods: {
}
};
</script>
<style scoped>
</style>
运行:
这里大家需要注意:
一个路由对象 (route object) 表示当前**的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的路由记录 (route records)。
路由对象是可变 (immutable) 的,每次成功的导航后都会产生一个新的对象。
路由对象出现在多个地方:
在组件内,即 this.$route
在 $route 观察者回调内
router.match(location) 的返回值
路由对象的属性:
$route.path
类型: string
字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
$route.params
类型: Object
一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
$route.query
类型: Object
一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
$route.hash
类型: string
当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。
$route.fullPath
类型: string
完成解析后的 URL,包含查询参数和 hash 的完整路径。
$route.matched
类型: Array<RouteRecord>
$route.name
当前路由的名称,如果有的话。(查看命名路由)
$route.redirectedFrom
如果存在重定向,即为重定向来源的路由的名字。
特别提醒:
$route为当前router跳转对象里面可以获取name、path、query、params等
$router为VueRouter实例,想要导航到不同URL,则使用$router.push等方法
也就是说如果我们期望从路由中获取一些参数等等情况,那么记得你要使用的是:this.$route而不是前面演示路由跳转时使用的this.$router