这里写目录标题
一、路由
idea创建vue项目:https://blog.csdn.net/qq_45716444/article/details/116771126
(1)路由的配置
这是我上一张写的https://blog.csdn.net/qq_45716444/article/details/116783474
(2)路由的概念
1、路由的概念
①参考链接
https://baijiahao.baidu.com/s?id=1668019099207124126&wfr=spider&for=pc
我觉得从设计的思想上来说路由是一个映射关系,直白来说就是一个url链接对应着一个组件(或多个组件,这个是嵌套路由)。
②路由的使用
要使用路由就先去配置,在上面的链接有配置的方法
路由整体的使用分x步
1、创建组件
2、在router.js中配置
3、配置main.js
4、在App.vue中添加 <router-view></router-view>
第一步-创建组件
创建vue组件,这里在src下面创建一个page文件,然后添加下面三个文件
index.vue|login.vue|register.vue,代码如下
//这是index.vue
<template>
<div>
首页
</div>
</template>
<script>
export default {
name: "index"
}
</script>
<style scoped>
</style>
//这是login.vue
<template>
<div>
登录
</div>
</template>
<script>
export default {
name: "login"
}
</script>
<style scoped>
</style>
//这是register.vue
<template>
<div>
注册
</div>
</template>
<script>
export default {
name: "register"
}
</script>
<style scoped>
</style>
第二步-配置router.js
在src下面创建一个router文件夹,在这个文件夹里面创建一个router.js文件,在
这个文件中写如下代码
//1、引入文件
import VueRouter from "vue-router";
//2、实例化VueRouter对象
const router = new VueRouter({
//这个是写映射关系的对象
routes:[
{
path: '/',redirect:'/login'
},
{
//这个是 把/index 与 ./page/index.vue 这个文件对应起来,到时候
//在url地址栏直接访问 localhost:8080/index 可以访问到index.vue这个文件
path: '/index',component:()=>import("@/page/index")
},
{
path: '/login',component:()=>import("@/page/login")
},
{
path: '/register',component:()=>import("@/page/register")
}
]
})
//3、抛出对象,最后会在main.js中引用
export default router
第三步-配置main.js
在src项目下找到main.js,添加以下代码
//导入路由文件,为了在App.vue中使用<router-view></router-view>
import VueRouter from "vue-router";
Vue.use(VueRouter)
//引入router.js中抛出的路由对象
import router from "@/router/router"
new Vue({
render: h => h(App),
//最后一定记得把router对象放到这里
router
}).$mount('#app')
2、路由的生命周期跟拦截器
①参考链接
https://blog.csdn.net/qq_38128179/article/details/100072962
②个人理解
这里我针对上面的进行一些总结:路由的生命周期主要分成三大部分,全局守卫/组件
守卫/路由守卫。
那什么是全局守卫呢?全局守卫就是在路由开始跳转到结束转的整个过程,这个跳
转,是所有的路由跳转。 也就是说,无论是从首页跳转到登录页,还是注册页跳转到登
录页都会触发全局守卫 对应的函数(钩子函数),我们的重点就是这个过程里面的
beforeEach ,做拦截。
那什么是全局守卫呢?顾名思义,那写函数(钩子函数)的作用范围是在单个组件内,也就是在一个Vue的实例中
最后一个路由守卫,它的作用域是在路由VueRouter中的routes单个对象中
路由里面的函数为什么叫钩子函数?链接在下面
https://blog.csdn.net/hhtSeeTheWorld/article/details/113525999
③拦截器思路分析
在写拦截器之前,我们来模拟一个场景。在登录页,我们需要经过登录才能进入
首页,所以在我们没有登录之前,我们就不能访问首页,那这个路由请求是不是得栏
截下来。那我们应该怎么实现呢?
我们跳转的时候,是要输入一个url,那我们就检查这个url。如果我们登录了,
就可以进入,如果没有登录就拦截。所以,我们要判断url吧,要判断是否登录吧。
判断url的话,可以来一个白名单(数组存一下不用登录就可以进入的页面路由就行
了)。判断是否登录过,我们可以把登录过的信息存到浏览器缓存中,用到的时候再拿出来就行了。
那我们在路由的生命周期中的哪一个过程进行拦截呢??
我们要判断所有的请求,那肯定是在全局中守卫中拦截,也就是说beforeEach |
beforeResolve 两个,为啥是这两个,而不是三个,因为afterEach没有next。
那到底要选哪一个??
对比下面那张图,其实会发现。beforeEach | beforeResolve 周期位置不一样,我们
既然要拦截,那被拦截下来的就没必要执行下面的那么多了,直接在beforeEach拦截就行了
④上面的可以忽略–这里拦截代码才是重要
这里我们的重点是要存一个 登录的信息 还有存一个白名单路由
//这个是在 src/router/router.js 中写的代码。注意这个代码是跟上面的连贯下来的,上面的步骤连贯下来的,上面刚刚开始写路由那里
import {Message} from "element-ui"
const notNeedLogin = ["/login"] //白名单,这个/index,在路由配置中有
router.beforeEach((to,from,next)=>{
//判断请求路由是否是白名单的,如果不是就返回-1
if (notNeedLogin.indexOf(to.path) == -1){
//如果路由不是白名单中的,那就判断是否登录,如果每登录就拦截(不执行next())
if(localStorage.getItem('token') == null){
next("/login")
Message.warning("请登录")
}
}
next()
})
//下面代码放到login.vue中,全部覆盖啊,把login.vue中的内容全部换成下面的就行了
<template>
<div>
登录
<el-button @click="token">存token</el-button>
<el-button @click="l">首页</el-button>
<el-button @click="r">退出</el-button>
</div>
</template>
<script>
export default {
name: "login",
methods:{
token(){
//把token存到缓存
localStorage.setItem("token","sdsd")
},
l(){
this.$router.push('/index')
},
r(){
//把token移除缓存
localStorage.removeItem('token')
}
}
}
</script>
<style scoped>
</style>
二、嵌套路由
嵌套路由描述
嵌套路由就是在上面写的一个路由里面再写子路由。然后最终的显示效果是子路由的
页面再加上父路由的页面效果。这里主要是要解决什么问题呢?
我们再来描述一下一个场景,当我们主页需要一个布局,而布局是整个主页的重要部
分,然后布局里面的东西是不停的在变化,也就是说,我们有10个页面,都需要到这个
布局。如果使用单路由的话,我们会给每一个组件都复制上重复的代码,就很麻烦,那
我们可不可以利用路由去减少这个代码量呢,答案是可以的。描述是抽象的,下面我们
用视觉来体验一下这个案例
视觉体验
【1】导入element-ui https://blog.csdn.net/qq_45716444/article/details/116783474
【2】主页的布局
//复制到index.vue文件中,index的全部代码
<template>
<div style="height: 100%">
//这个是element组件 https://element.eleme.cn/#/zh-CN/component/container
<el-container style="height: 100%">
<el-aside width="200px" style="background-color: darkgrey">Aside</el-aside>
<el-container>
<el-header style="background-color: #42b983">Header</el-header>
<el-main style="background-color: #2c3e50">Main</el-main>
<el-footer style="background-color: skyblue">Footer</el-footer>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "index"
}
</script>
【3】引入问题我们在src/page下面多创建了r.vue和l.vue,然后我们这些页面都需要index.vue中的布局代码,除了复制粘贴代码可以实现,还有另一种,就是使用嵌套路由。
//l.vue
<template>
<div>
<h1 color="red">这个是l页面</h1>
</div>
</template>
<script>
export default {
name: "l"
}
</script>
<style scoped>
</style>
//r.vue
<template>
<div>
<h1 color="white">这个是r页面</h1>
</div>
</template>
<script>
export default {
name: "r"
}
</script>
<style scoped>
</style>
【4】嵌套路由代码
//代码写在router/router.js中
//2、实例化VueRouter对象
const router = new VueRouter({
//这个是写映射关系的对象
routes:[
{path: '/',redirect:'/login'},
{
//这个是 把/index 与 ./page/index.vue 这个文件对应起来,到时候
//在url地址栏直接访问 localhost:8080/index 可以访问到index.vue这个文件
path: '/index',component:()=>import("@/page/index"),
//下面这个是嵌套路由
children:[
{path: '/r',component: () => import("@/page/r")},
{path: '/l',component: () => import("@/page/l")}
]
},
{path: '/login',component:()=>import("@/page/login")},
{path: '/register',component:()=>import("@/page/register")}
]
})
//index.vue的代码,全部代码
<template>
<div style="height: 100%">
<el-container style="height: 100%">
<el-aside width="200px" style="background-color: darkgrey"></el-aside>
<el-container>
<el-header style="background-color: #42b983"></el-header>
<el-main>
//这个不能拉下
<router-view></router-view>
</el-main>
<el-footer style="background-color: skyblue"></el-footer>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "index"
}
</script>
【5】运行效果