发现自己对路由这方面的知识比较薄弱...所以这次来个笔记总结一下自己不熟的点。
路由传参
vue 路由传参的使用场景一般都是应用在父路由跳转到子路由时,携带参数跳转。传参方式可划分为 params 传参和 query 传参,而 params 传参又可分为在 url 中显示参数和不显示参数两种方式,这就是vue路由传参的三种方式。
params
传参(显示参数)获取路由参数方式:this.$route.params.参数
声明式: router-link
就是在模板中使用<router-link>标签实现路由跳转。
提示: routerlink默认渲染为带有正确连接的<a>标签,可以通过tag属性自己修改。
const routes = [
{
path: '/',
component: FatherComp,
//子路由
children:[ {
name: 'child',
path: '/son/:id',
component: son
}]
},
{
name: 'page',
path: '/page/:id', //这个为动态路由,开头的斜杠为必需的
component: page
}
]
现在点击第一个按钮:
现在点击另一个按钮, 因为是子路由,只要在这个页面上放一个<router-view>的标签, 子路由的内容就会显示在里面。
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。使用该方式传值的时候,需要子路由提前配置好参数
可以看到在地址栏里是显示参数的。
编程式this.$router.push
也就是在setup里面写跳转
点击后就会跳转,效果相同。
本文由“壹伴编辑器”提供技术支持
params
传参(不显示参数)这个我研究了好久啊, 这个方法大概就是这样的:
路由这么写:
{
name: 'page',
path: '/page/:id', //注意这里只有id动态参数
component: page
}
但是我传值的时候非要多传一个token:
这样是不会显示在url中的
不知道怎么做到的刷新就不显示, 但是我查了一下:
难怪呢,我还降级了vue-router,结果报错了就算了
编程式this.$router.push
route.push({ name: 'page', params: { id: "1234" } });
本文由“壹伴编辑器”提供技术支持
query
传参(显示参数)获取路由参数方式: this.$route.query.id
声明式: router-link
路由:
{
name: 'page',
path: '/page',
component: page
}
query传参:
<router-link :to="{name: 'page', query: {id: 123, token: '123345'}}">
编程式this.$router.push
<button @click="toPage">路由传参</button>
const toPage = () => {
route.push({ name: 'page', query: { id: "1234" } });
};
得到的结果:
在路由里没有定义的参数也可以传,顺序也是没有关系的。
路由守卫
路由守卫的官方解释:
导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
简单的说,导航守卫就是路由跳转过程中的一些钩子函数。路由跳转是一个大的过程,这个大的过程分为跳转前中后等等细小的过程,在每一个过程中都有一函数,这个函数能让你操作一些其他的事儿的时机,这就是导航守卫。
钩子函数执行后输出的顺序截图
(图源知乎)
导航守卫分为:全局的、单个路由独享的、组件内的三种。分别来看一下:
【全局的】:是指路由实例上直接操作的钩子函数,特点是所有路由配置的组件都会触发,直白点就是触发路由就会触发这些钩子函数,如下的写法。钩子函数按执行顺序包括beforeEach、beforeResolve、afterEach三个。
参数:
to:目标路由对象;
from:即将要离开的路由对象;
next:它是最重要的一个参数, 就是放行的意思,没有next()的话,路由是不会进行跳转的。
[beforeEach]:在路由跳转前触发,参数包括to,from,next(参数会单独介绍)三个,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。
现在我做一个登录模拟
路由:
const routes = [
{
path: '/',
component: FatherComp,
},
{
name: 'index',
path: '/index', // 首页
component: index
}, {
name: 'login',
path: '/login', //登录页面
component: () => import('../views/login.vue')
}
]
路由守卫:
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
router.beforeEach((to, from, next) =>{
console.log(to);
if(to.fullPath == '/' || to.path == '/login') {
// 第一个判断是因为我们所在页路由就是'/',需要直接next()
// 第二个判断的原因是如果登录失败会调回login页,会造成无限会跳,程序出错
next() // 一定要next(), 否则是跳转不到这个页面的
} else {
console.log(to);
console.log(from);
if(to.fullPath.includes('?token')) {
// 如果要跳转的url里面包括了token,那就登录成功
console.log('登录成功');
next()
} else {
console.log('登录失败');
// 否则就登录失败, 跳转到登录页
next('/login')
}
}
})
export default router
点击button触发事件实现跳转
route.push({ name: "index", query: { token: "xxxxxx" } });
结果:
现在把它改成不携带token
route.push({ name: "index", query: { id: "xxxxxx" } });
就显示登录失败了。
本文由“壹伴编辑器”提供技术支持
【路由独享的】是指在单个路由配置的时候也可以设置的钩子函数。目前它只有一个钩子函数beforeEnter
[beforeEnter]:和beforeEach完全相同,如果都设置则在beforeEach之后紧随执行,参数to、from、next
用这个验证登录也会简单一些,现在将验证登录改造一下,将这个守卫单独放在一个路由里,就不用考虑其他路由了:
{
name: 'index',
path: '/index',
component: index,
beforeEnter: (to, from, next) => {
if(to.fullPath.includes('?token') ) {
console.log('登录成功');
next()
} else {
console.log('登录失败');
next('login')
}
}
}
用起来结果也是一样的,而且也不用担心路由一直无限回跳。
其他的用户应该也比较少,就先不写啦。
呃,路由模式hash和history一直搞不懂,主要是我自己测试不出来,结果不一样...先不写了,暂时跳过,下次继续查。
token/token/session
关于这个我真的看了好多视频查了好多资料。
就说一些自己的理解吧。首先这三者的共同点就是都是用于鉴权的(验证身份的),为什么我们登录过一次某网站以后,第二次就可以不用登录直接进入呢,就是因为我们携带了身份信息,服务器知道我们的身份信息后,就直接让我们进入。但是也不是一劳永逸的,到了一定时间还是要重新登录,因为身份信息可能会过期。
cookie
误解:cookie是缓存
cookie的本质是一小段的文本信息,格式的字典,key=value。cokie的名称不是固定的,是由开发自定义的。
会话cookie:保存在内存,当浏览器的会话关闭之后自动消失
持久cookie:保存在硬盘,只有当失效时间到期了才会自动消失
{name值value值Domain:域名Path:路径,expries:失效时间size:大小
查看当前项目的cookie:F12->application-->cookie
查看所有的cookie:高级
拿我的举例:
第一步:客户端第1次请求服务器的时候,这个时候服务器产生了cookie,然后通过响应头里面的set-Cookie把cookie的信息传输到客户端。
第二步:当客户端从第2次开始直到后面的所有请求,在请求头的Cookie都会自动地带上以上的Cookie的信息。从而实现鉴权。
因为Cookie是保存在客户端里面,cookie的数据可以在客户端被截获。对于一些机密的数据用户名和密码,银行卡号,支付密码,身份证号码,需要更加好的方法来保存信息。
Sessoin
session它是通过cookie来传值的。
当客户端第一次登录服务器的时候,那么这时候,服务器就会产生session,(起名不固定),一般是一个比较长的经过加密的字符串,sessionid在服务器和客户端分别都保存了一份,然后通过cookie的鉴权的方式实现session的鉴权,session的生命周期默认是30分钟
首先,session的存储是需要空间的;其次,session的传递一般都是通过cookie来传递的。而token在服务器端是可以不需要存储用户的信息的,token的传递方式也不限于cookie传递;当然,token也是可以保存起来的。
Token令牌
浏览器第一次访问服务器,根据传过来的唯一标识userId,服务端会通过一些算法,如常用的SHA256算法,然后加一个密钥,生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端。客户端将token保存起来,下次请求时,带着token。服务器收到请求后,然后会用相同的算法和密钥去验证token,如果通过,执行业务操作;如果不通过,返回不通过信息。
对称加密:DES,AES
双钥加密:RSA,一般用于金融项目里面做签名
只加密不解密:MD5,SHA系列。
编码格式:Base64
accesss token:时效15分钟到2小时之间
refresh token: 时效15天
本文由“壹伴编辑器”提供技术支持
面试题 : cookie,session,token的相同点和区别是什么 ?
相同点:都是用于身份验证(鉴权)的,都是服务器产生的
不同点:
最后再放一下我觉得写得比较好的资料吧:
文由“壹伴编辑器”提供技术支持
vue3使用proxy实现跨域
这个东西搞了我一天...终于搞明白
我现在对http://www.zhangxinxu.com/study/201802/cros-ajax.php这个网址直接请求。
封装的请求:
点击按钮发起请求:
得到的结果显示为跨域问题:
现在我设置一下开发时的基准地址baseURL,建立一个.env.development的文件,这个之前写过,就是在npm run serve时会执行的。如果是生产环境下那就是.env.production文件,会在npm run build的时候执行。在这次举例中我使用的的是开发环境。
而请求的地址为 "/201802/cros-ajax.php"
所以发请求时的url是baseURL+发请求时的url。
拼在一起那就是 "/study/201802/cros-ajax.php"
那么现在就需要在vue.config.js中设置devServer
devServer: {
allowedHosts: "all",// 此选项允许你添加白名单服务,允许一些开发服务器访问。
open: false, // 编译完成是否打开网页
host: 'localhost', // 指定使用地址,默认localhost,0.0.0.0代表可以被外界访问
port: 8081, // 访问端口
https: false, // 用于设置是否启用https
hot: 'only', // 开启热加载
proxy:{
// 以下就是代理
'/study': { //如果url匹配到'/study', 那么就会代理到target的路径上
target: 'http://www.zhangxinxu.com', //这个就是目标路径
secure:false,
changeOrigin: true,
ws: true, // 是否代理 websocket
pathRewrite: {
//重写 url 的 path 部分
}
}
}
}
现在来解释一下代理是怎么做的:
上面已经写了,路由拼接起来为"/study/201802/cros-ajax.php",那么proxy检测到这个路由确实有'/study',于是这个url就变成了
http://www.zhangxinxu.com/study/201802/cros-ajax.php
下面的pathRewrite的作用:
假如我写的是: pathRewrite: {'^/study': ' '}, 那么就会将路由的一部分重写,此时路由就会变成:http://www.zhangxinxu.com/201802/cros-ajax.php
现在重新发请求看看结果: