⑥ vue-router
-
多页面应用 MPA(Multiple Page Application)
-
单页面应用 SPA(Single Page Application)
1 安装和引入
script 标签引入
在 Vue 后面加载
vue-router,它会自动实现安装
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
npm 方式(推荐)
Vue-Router是通过插件的形式来扩展 Vue 的功能,所以要使用它,必须要通过Vue.use()方法安装路由功能
import Vue from 'vue';
import VueRouter from 'vue-router';
// 调用Vue.use手动安装,之后才能在实例中通过this.$route访问
Vue.use(VueRouter);
2 使用
2.1 步骤
-
引入
vue-router -
使用
vue-router(script标签引入方式自动完成) -
实例化
router并配置参数 -
把
router实例注入到vue实例中 -
在组件中使用
2.2 参数配置
mode:路由模式
-
hash(默认) -
history
需要后端配置,任意路径返回
index.html(IE9中会自动降级到hash模式)
routes:路由配置
核心配置,包含所有的页面配置
-
name:设置路由名称,方便执行路由跳转 -
path:访问这个页面的路径 -
component:指定路由组件(显示到<router-view/>中的组件) -
components:在多视图组件中,给每个命名视图指定路由组件一般用于多个
view-router的场景 -
props(Boolean|Object|Function):路由组件传参 -
redirect(String|Object|Function):重定向 -
children(Array):嵌套路由配置子路由一般使用相对路径的path
2.3 显示路由内容 <router-view/>
用于显示
component路由组件内容
name命名视图(默认:default)
2.4 导航(如何实现路由跳转)
2.4.1 声明式导航
利用内置组件标签来实现路由跳转
<router-link>
-
to(Sting|Object):设置目标路由的链接。点击后,跳到目标路由 -
tag:让<router-link>渲染成某种标签(默认:a) -
active-class:匹配路由时<router-link>使用的类名 -
exact-active-class:精确匹配路由时<router-link>使用的类名 -
replace: 跳转到目标路由且不留下 history 记录 -
event: 触发路由的事件(默认:click)
2.4.2 编程式导航
利用
Router实例(this.$router)的方法实现路由跳转
$router.push(location)
this.$router.push('/home');
// 等同于:<router-link to="/home"></router>
// 对象
this.$router.push({ path: '/home' })
this.$router.push({ name:'Home' })
// 等同于:<router-link :to="{name:'Home'}"></router>
$router.replace(location)
类似于
router.push(),唯一不同的是它不会向history添加新记录
$router.go(n) / $router.back() / $router.forward()
在
history记录中向前或者后退多少步,类似window.history.go(n)
2.5 路由传参
在组件中通过
this.$route获取当前路由信息,包含传入的参数params/query等
2.5.1 跳转时传参
params
- 通过
this.$route.params获取,可通过动态路由、导航时传入等方式传入,刷新后参数不存在
// params传参,只支持name方式跳转
this.$router.push({ name: 'Goods', params: { id:123 }})
// 动态路由传参
this.$router.push('/goods/123')
query 传参
- 通过
this.$route.query获取,可通过路由导航时传入,刷新后参数依然存在
this.$router.push('/goods?id=123')
this.$router.push({ path:'/goods', query: { id: 123 }})
动态路由传入
//路由组件
const User = {
template:`<div>{{$route.params.id}}</div>`
}
//路由配置
routes:[{
path:'/user/:id',
component:User
}]
-
注意:当路由从
/user/zhoutest导航到/user/luotest,组件实例会被复用(因为两个路由都渲染同个组件User,比起销毁再创建,复用则显得更加高效)因此不会执行组件的生命周期钩子函数。解决方案:-
利用
watch监测$route对象变化 -
beforeRouteUpdate路由守卫
-
const User = {
watch: {
'$route' (to, from) {
// 对路由变化作出响应...
}
},
beforeRouteUpdate (to, from, next) {
//to:目标路由
//from:当前路由
//一定要调用next()方法才可进入目标路由
}
}
2.5.2 定义时传参
props
以上通过
$route.params.id获取参数方式较为繁琐,而且组件与路由高度耦合,可以使用 props 组件传参的方式解耦
Boolean 模式
如果 props 被设置为 true,内部会自动把
route.params设置为组件属性
const User = {
props:['id'],
template:`<div>{{id}}</div>`
}
routes:[{
path:'/user/:id',
component:User,
props:true //等效于:<User v-bind="route.params"/>
}]
Object 模式
如果
props是一个对象,它会被按原样设置为组件属性(v-bind="{...}"),一般用于静态数据
const User = {
props:['myname'],
template:`<div>{{myname}}</div>`
}
routes:[
{
path:'/user/:id',
component:User,
props:{myname:'zhoutest'}
// 等效于:<User v-bind="{ myname: 'zhoutest' }"
}
]
Function 模式
实现更灵活的参数传递,如可以把 query 参数传入组件
const Settings = {
props:['query'],
template:`<div>{{query}}</div>`
}
routes:[
{
path:'/settings',
component:Settings,
props:(route) => ({ query: route.query.q })
}
]
3 导航守卫(路由钩子函数)
3.1 路由跳转的过程
3.1.1 跨组件跳转

3.1.2 组件重用跳转

- 每个路由守卫中都要调用
next()
3.2 路由守卫
3.2.1 全局守卫
所有的路由切换都会执行,一般写在路由配置文件中
-
router.beforeEach(fn)-
to -
from -
next()
-
-
router.afterEach(fn)-
to -
from
-
3.2.2 路由独享的守卫
写在路由配置中
-
beforeEnter(fn)-
to -
from -
next()
-
3.2.3 组件内的守卫
-
beforeRouteEnter(fn): 此时组件实例还没被创建,因此无法访问 this-
to -
from -
next()
-
-
beforeRouteUpdate(fn)-
to -
from -
next()
-
-
beforeRouteLeave(fn)-
to -
from -
next()
-
浙公网安备 33010602011771号