// 导入vue-router对象
import VueRouter from "vue-router";
import Hebei from "../pages/hebei.vue";
import Henan from "../pages/henan.vue";
import City from "../pages/city.vue";
// 创建路由器对象(在这个路由器对象中配置路由)
const router = new VueRouter({
// 在这里配置所有的路由规则
routes : [
// 这就是一个路由
{
// 路由由path和component组成
// 这个看作key
// 只要路径检测到的是/hebei就切换到这个组件
path : "/hebei",
// 这个就是路由的value,路由的value是一个组件
component : Hebei,
meta : {
title : "河北省"
},
// children子路由
children : [
// 配置子路由
{
// 对于子路由来说,path不用添加/,以/开始
// 系统会自动添加
// path : "/hebei/shijiazhuang",
name : "shi",
path : "sjz/:a1/:a2/:a3",
// :形式可以将后续的内容视为数据
component : City,
// 在路由中进行的配置
// props : {
// x : 'Jack',
// y : 'Rose'
// }
// props含有函数式写法
// props($route){
// // 当前路由对象会被自动传递过来
// // 将来取值时会自动调用函数
// // 调用这个函数对象会获取到当前路由对象
// return {
// a1 : $route.params.a1,
// a2 : $route.params.a2,
// a3 : $route.params.a3
// }
// // 需要在方法最后返回对象
// }
// 这种方式只支持params方式的传参,不支持query方式
// 原理是将params直接内部转为props对象
props : true,
// 给路由对象添加自定义属性的话,需要在路由对象的meta路由源中定义
// 需要鉴权的属性
meta : {
isAuth : true,
title : "石家庄"
}
},
{
// 可以给路由起名字,用来防止过长导致path写一大串
name : "han",
// 数据是动态传过来的,我们只负责接收,所以两个子路由可以共享一个组件
path : "hd/:a1/:a2/:a3",
component : City,
// props($route){
// return {
// a1 : $route.params.a1,
// a2 : $route.params.a2,
// a3 : $route.params.a3
// }
// }
props : true,
meta : {
isAuth : true,
title : "邯郸"
}
}
]
},
{
path : "/henan",
component : Henan,
meta : {
title : '河南省'
}
}
]
});
// 全局前置守卫,在暴露之前创建之后即可
// beforeEach中的callback什么时候被调用呢,在每一次切换任意路由组件之前
// callback没有要求,可以是普通函数也可以是箭头函数
// from是一个路由对象
// callback函数有三个参数,to from next
// from是一个路由对象有name,path,component等属性就是上面的路由对象,这里表示的是起点路由
// to表示往哪去,也是一个路由对象,表示到哪去
// next参数是一个函数,调用这个函数以后,表示放行
router.beforeEach((to,from,next) => {
// 页面初始化的时候,from和to相同
// 每一次切换路由组件都会执行
let loginName = "Jack";
// 目前需要鉴定权限的路由少,如果多会导致这里繁琐
if(to.meta.isAuth){
if(loginName === "Rose"){
// 有权限才修改名字
// document.title = to.meta.title;
// 放行
next();
}
else{
alert("您没有权限");
}
}
else{
// 有权限才修改名字
// document.title = to.meta.title;
// 放行
next();
}
});
// 全局后置路由首位
// 初始化执行一次,以后每次切换执行一次,以后每一次切换任意一个路由组件调用一次
// 这个回调函数只有to和from,没有放行用的next
router.afterEach((to,from) => {
// 相对于前置修改方式,切换动作稍慢一点,但是代码复用率更高,不会造成大量冗余
// 短路或,初始值为false就执行后半句
// 如果前面为true不考虑后面,因为前面有值而不是undefined(被视为false)
document.title = to.meta.title || "欢迎使用本系统";
});
// 导出路由器对象
export default router;
<template>
<div>
<MyHeader></MyHeader>
<div>
<!-- 因此对于我们普通的组件来说一共有九个回调函数 -->
<!-- 八个生命周期和nextTick() -->
<!-- nextTick在dom下一次渲染的时候执行 -->
<!-- 路由组件还要多两个分别是激活和未激活两个钩子函数 -->
<h1>省份</h1>
<!-- 在默认的情况下,我们切换组件会导致原组件被销毁 -->
<button @click="forward()">前进</button>
<button @click="back()">后退</button>
<button @click="forwardTwo()">前进2步</button>
<button @click="backTwo()">后退2步</button>
<ul>
<!-- 如果使用的是路由方式,就不能使用a标签超链接了 -->
<!-- 需要使用vue-router提供的标签router-link -->
<!-- <li><a href="/hebei">河北省</a></li> -->
<!-- <li><a href="/henan" class="selected">河南省</a></li> -->
<!-- router-link将来会被自动编译为a标签 -->
<!-- active-class点中激活,点中的时候激活这个样式 -->
<li><router-link to="/hebei" active-class="selected">河北省</router-link></li>
<li><router-link to="/henan" active-class="selected">河南省</router-link></li>
</ul>
</div>
<!-- 路由视图,起到一个占位的作用 -->
<!-- <keep-alive>
这个标签下所有的组件在组件切换的时候都不会被杀死
这个标签下所有的组件切换都不会遭到销毁
<router-view></router-view>
</keep-alive> -->
<!-- <keep-alive include="Hebei"> -->
<keep-alive :include="['Hebei','Henan']">
<!-- 这样两个组件就都可以保持了 -->
<!-- 把组件的配置的name属性下的名字放到这里可以保证这个组件切换不被杀死 -->
<!-- 这个组件不会被销毁,会保留状态 -->
<!-- 如果需要保持多个组件的状态则应该给予一个数组 -->
<router-view></router-view>
</keep-alive>
</div>
</template>
<script>
import MyHeader from "./components/MyHeader";
export default {
name : "App",
components : {MyHeader},
methods : {
forward(){
this.$router.forward();
},
back(){
this.$router.back();
},
forwardTwo(){
this.$router.go(2);
},
backTwo(){
this.$router.go(-2);
}
}
}
</script>
<style>
.s1{
margin-left: 100px;
}
.s2{
margin-left: 100px;
}
.selected{
background-color: aqua;
}
</style>
<template>
<div>
<!-- 组件分为普通组件和路由组件 -->
<div class="s1">
<!-- 栈数据结构 -->
<!-- stack栈一种数据结构,当我们的元素进入称为入栈,或压栈push -->
<!-- 进入的第一个元素在栈底部的我们称之为栈底元素 -->
<!-- 默认情况下,栈当中是一个指针的,这个指针在默认情况下指向栈顶元素 -->
<!-- 每次有新的元素入栈后,栈的指针都会自动向上移动指向栈顶的那个元素 -->
<!-- 栈顶元素先出栈,出栈,弹栈pop -->
<!-- 栈数据结构特点,遵循先进后出,后进先出原则 -->
<h2>市区</h2>
<ul>
<li>洛阳</li>
<li>开封</li>
<li>安阳</li>
<li>郑州</li>
</ul>
<!-- 浏览器的历史记录就是存在栈这种数据结构里面的 -->
<!-- 历史记录存放到栈有两种不同的模式 -->
<!-- 第一种,push模式 -->
<!-- 以追加的方式入栈 -->
<!-- 第二种,replace模式 -->
<!-- 以替换栈顶元素的方式入栈 -->
<!-- 浏览器默认的模式是push模式 -->
<!-- 操作浏览器上的前进后退并不会删除栈当中的历史记录,只是向前和向后移动指针 -->
<!-- 只是移动了指针指向的元素 -->
<!-- 栈内的元素没有发生变化,变化的只有指针位置 -->
</div>
<router-view></router-view>
</div>
</template>
<script>
export default {
name : "Henan",
beforeDestroy(){
console.log("啊,组件去世了!")
},
}
</script>
<style>
</style>
<template>
<div>
<!-- 组件分为普通组件和路由组件 -->
<div class="s2">
<h2>县区</h2>
<ul>
<!-- query形式接收 -->
<!-- <li>{{ $route.query.a1 }}</li>
<li>{{ $route.query.a2 }}</li>
<li>{{ $route.query.a3 }}</li> -->
<!-- params形式接收 -->
<li>{{ a1 }}</li>
<li>{{ a2 }}</li>
<li>{{ a3 }}</li>
<!-- 遍历query的方式 -->
<!-- <li v-for="propertyValue,propertyName in $route.query" :key="propertyName">{{ propertyValue }}</li> -->
<!-- 遍历params的方式 -->
<!-- <li v-for="propertyValue,propertyName in $route.params" :key="propertyName">{{ propertyValue }}</li> -->
</ul>
</div>
</div>
</template>
<script>
export default {
name : "City",
// 因为我们的组件是通过路由唤醒的,因此路由会把这个配置props传递过来
// 我们就可以在这里拿到props
props : ['a1','a2','a3'],
mounted(){
// 所有的路由组件都有一个$route,通过这个属性可以获取到路由组件关联的路由对象
console.log(this.$route);
// 路由对象中有一个query属性,通过这个query属性可以接收到query方式传过来的数据
console.log(this.$route.query);
// 接收的params数据
console.log(this.$route.params);
},
// 使用计算属性的方式
computed : {
params(){
return this.$route.params;
}
}
}
</script>
<style>
</style>