vue-router
vue-router 中常用的路由模式
hash hashchange
history
- HTML5 History API( pushState、replaceState)
- 这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面,这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础
路由组件复用,导致路由参数
- 用 key 阻止复用
js
<router-view :key="$route.fullPath" />
- 通过 watch 监听路由参数再发请求
js
watch: { //通过watch来监听路由变化
"$route": function(){
this.getData(this.$route.params.xxx);
}
}
失活组件的beforeRouterLeave => 全局的beforeEach => 重用组件的beforeRouterUpdate => 路由组件的beforeEnter => 解析异步路由组件=> 被激活组件的beforeRouterEnter => 全局的beforeResolve => 导航被确认 => 全局的afterEach => 触发Dom更新 => 调用beforeRouterEnter的next函数
路由钩子函数
全局前置守卫: beforeEach
全局后置钩子: afterEach
路由独享钩子: beforeEnter
js
const router = new VueRouter({
routes: [
{
path: '/home',
component: Home,
beforeEnter: (to, from, next) = {
// to do somethings
// 参数与全局守卫参数一样
}
}
]
})
- 组件内钩子: beforeRouteEnter
js
const Home = {
template: `<div></div>`,
beforeRouteEnter(to, from, next){
// 在渲染该组件的对应路由被 confirm 前调用
// 不能获取组件实例 ‘this’,因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next){
// 在当前路由改变,但是该组件被复用时调用
// 例:对于一个动态参数的路径 /home/:id,在/home/1 和 /home/2 之间跳转的时候
// 由于会渲染同样的 Home 组件,因此组件实例会被复用,而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 'this'
},
beforeRouteLeave(to, from, next){
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 'this'
}
}
切换路由后,新页面要滚动到顶部或保持原先的滚动位置
js
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
}
});
什么是命名视图
components 配置 (记得加上s)。
js
function load(component) {
return resolve => require([`views/${component}`], resolve);
}
const routes=[
{
path: '/',
redirect: '/home',
name: 'layout',
component: load('layout'),
children: [
{
path: '/home',
name: 'home',
components: {
default: load('main'),
header: load('header'),
sider: load('sider')
},
meta: {
title: '首页'
},
},
]
}
]
vue
<template>
<div>
<div>
//...头部导航
<router-view name='header'></router-view>
<div>
//...侧边栏导航
<router-view name='sider'></router-view>
</div>
<div>
//...主内容
<router-view/>
</div>
</div>
</template
路由组件和路由为什么解耦
因为在组件中使用 $route
会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL
上使用,限制了其灵活性
使用 props 来解耦
props为true,route.params将会被设置为组件属性。 props为对象,则按原样设置为组件属性。 props为函数,http://localhost:8036/home?id=123,会把123传给组件Home的props的id
js
const Home = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/home/:id', component: Home, props: true},
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/home/:id',
components: { default: Home, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
{ path: '/home', component: Home, props: {id:123} },
{ path: '/home', component: Home, props: (route) => ({ id: route.query.id }) },
]
})
如果vue-router使用history模式,部署时要注意什么?
要注意404的问题,因为在history模式下, 在Ngnix中将所有请求都转发到index.html上就可以了。
router-view
matched是一个由record类型元素组成的,其index 由 0 到最后, 因此是父--->子。 而routerView 的 render 函数通过定义一个 depth 参数,来判断当前嵌套的路由是位于 matched 函数的哪个index,然后取出对应的record对象,渲染器对应的组件。