目录
vue-Router实现了在不刷新页面的情况下,通过改变路由的URL去改变页面的视图
hash模式
修改hash值,渲染hash值下对应的组件;
也可通过浏览器前进、后退操作,对hashchange事件进行监听,当hash值发生变化时,渲染该hash值下对应的组件
hash值改变的同时,浏览器会自动修改路由栈
window.location
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<a href="#/home">Home</a>
<a href="#/a">页面A</a>
<div id="page"></div>
<script>
window.addEventListener("hashchange", function (event) {
let hashId = window.location.hash;
if (hashId == "#/home") {
document.getElementById("page").innerHTML = "首页";
} else if (hashId == "#/a") {
document.getElementById("page").innerHTML = "A页面";
}
});
</script>
</body>
</html>
点击Home,效果如下
点击home,再点击页面A, history栈长度变化。说明浏览器会自动修改历史访问栈
history模式
history模式就是利用pushState()、replaceState()改变历史记录, 同时渲染响应路由组件;
也可通过浏览器前进、后退操作,监听popstate事件实现浏览器路由跳转时, 同时渲染响应路由组件;
window.history
length
历史记录个数,history.back()操作不会减少记录个数
state
可认为是该页面的接收参数,根据pushState()方法可向具体URL传参state
pushState(state, title, url)
- 修改浏览器历史记录,入栈,但是不操作浏览器的前进、后退;
- 如果为绝对路径,需要与当前路径同源
replaceState(state, title, url)
替换当前历史记录
back():操作浏览器后退
forward():操作浏览器前进
go():操作浏览器跳往第几个栈记录
代码实现
<template>
<div>
<div>home页</div>
<div @click="pushUrl('/home')">点我</div>
</div>
</template>
<script>
export default {
name: "",
data() {
return {
};
},
mounted() {
// 监听浏览器前进、回退事件
window.addEventListener("popstate", (event) => {
console.log("--------popstate---------");
console.log(event.state)
if (event.state.state == "/home") {
//渲染对应的组件
} else if (event.state == "/a") {
//渲染对应的组件
}
});
},
methods: {
add() {
this.a++;
},
pushUrl(url) {
window.history.pushState({page: url}, "page 2", url); //此时算上首页,栈中共有两条记录
if (event.state.state == "/home") {
//渲染对应的组件
} else if (event.state == "/a") {
//渲染对应的组件
}
},
},
};
</script>
<style lang="less" scoped></style>
路由守卫事件
路由生命周期执行的先后顺序
刷新进入页面A
从'/a'进入’/b'
从'/a'进入’/a?name=aa'
路由与组件声明周期的先后顺序
进入A页面:执行顺序,路由的声明周期 > 组件的生命周期
离开A页面(从 '/a' 到 '/' ):执行顺序,路由的声明周期 > 组件的生命周期
router-link 与 a
- <a>标签去往的路由会重新渲染页面、可以使用_target="_blank"新打开一个标签页面
- <router-link>可以进行replace操作
$route.matched
是一个数组,匹配当前的路由一级路由的祖父级
const routes = [
{
path: '/a',
name: 'a',
component: () => import("@/views/A.vue"),
children: [
{
path: 'c',
name: 'c',
component: () => import("@/views/child/C.vue"),
}
]
},
]
访问'/a/c'时,matched如下
问题
不同路由跳转到相同页面,缓存问题
现象:后台管理界面,存在二级路由,从'/home/a' 切换到 '/home/b' ,但当前这两个路由对应的是同一个页面组件,此时会出现缓存现象,第二次访问不会进行mounted之前周期的渲染。
//router.js
const routes = [
{
path: '/home',
name: 'home',
component: Home,
meta: { static: true },
// /a , /b 对印着同一个页面
children: [
{ path: 'a', componentPath: 'views/child/A.vue' },
{ path: 'b', componentPath: 'views/child/A.vue' }]
},
]
解决方法:
1.在home的route-view标签中设置key,是vue-router认为这是两个不同的路由
<template>
<div id="home">
<div @click="pushRouter('/b')">点击跳转B</div>
<div @click="pushRouter('/a')">点击跳转A</div>
<router-view :key="$route.fullPath"></router-view>
</div>
</template>