这篇文章将为大家详细讲解有关怎么在Vue中实现路由快照,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
// router-snapshot.js
// https://github.com/dankogai/js-base64
import { Base64 } from 'js-base64';
function beforeRouteEnterHandler (vm, {key, ext}) {
// 获取路由绑定字段
const routeBindKeys = vm.$options[ext] || [];
// 获取路由绑定部分的加密字符串
const routeParamsString = vm.$route.query[key];
// 解密并转换为JSON
let routeParamsJSON;
try {
routeParamsJSON = JSON.parse(Base64.decode(routeParamsString));
}catch (e) {
routeParamsJSON = {};
}
routeBindKeys.forEach(attr => {
// 使用vue的是指方式,若浏览器没有缓存值,则获取组件默认值
vm.$set(vm, attr, routeParamsJSON.hasOwnProperty(attr) ? routeParamsJSON[attr] : vm[attr]);
// 追加属性反向监听,监听到的属性变化都会呈现在路由上
vm.$watch(attr, (value) => {
const query = vm.$route.query;
let routeSnapshotValueJSON;
try {
routeSnapshotValueJSON = JSON.parse(Base64.decode(query[key]));
}catch (e) {
routeSnapshotValueJSON = {};
}
routeSnapshotValueJSON[attr] = value;
const extendQuery = {};
extendQuery[key] = Base64.encodeURI(JSON.stringify(routeSnapshotValueJSON));
vm.$router.push({
query: {
...query,
...extendQuery
}
})
}, {
deep: true
});
})
}
export default {
install (Vue, {key = '_', ext = 'routeShot'} = {}) {
Vue.mixin({
// beforeRouteEnter (to, from, next) {
// console.log('beforeRouteEnter', to, from)
// next(beforeRouteEnterHandler)
// }
created () {
beforeRouteEnterHandler(this, {key, ext});
}
});
}
}
代码逻辑大致如下:
代码45行,注册该组件时,我们需要指定保存在URL query部分的键名,默认为_;同时指定绑定在组件上的拓展属性名,默认为routeShot;
代码21行,根据组件拓展属性,对这些拓展属性实施监听,将属性值的变化同步到路由中;
代码19行,在组件created阶段,获取路由参数并解析成组件属性,并将属性值同步到组件中;
代码13、25、31行对路由上的参数进行Base64的加密和解密;
组件的代码仅仅需要追加routeShot的配置即可:
<template>
<!-- 使用的iview库的Switch组件 -->
<Switch v-mode="switchValue"></Switch>
</template>
<script>
export default {
// 配置routeShot,指定该组件的switchValue属性映射到URL中
routeShot: ['switchValue'],
data () {
return {
switchValue: false
}
}
}
</script>
经过这样,无论你怎么刷新页面,被快照的属性都不会发生改变。另外,除了data属性,prop、computed属性也是可以绑定到URL上的。
什么时候用最适合?
目前来说,应用场景中最多的还是非安全性表单以及不需要持久化的数据。举几个例子:
表格中筛选项有很多的情况下,用户进行了大量的选择和填写操作,结果因为网络原因导致请求失败。待网络恢复后,用户重新刷新页面,先前的操作必须重新执行;一般情况中,用户不会随意更改浏览器的URL,在这种条件下,用户的刷新不影响上下文的环境,能给用户带来一定便利;
之前代码示例中,开关组件的值不交予服务端进行持久化,也是可以使用这种方式来保存操作的;
存在的问题
写完这个插件,面临了三个我认为比较重要的问题:
性能问题: 通过代码47-50行可以看出,早期设计是将插件应用在路由组件中的,但是在后期的测试和使用中,发现还有很多组件不是注册在路由中的,也就是父子组件,这样的组件无法被路由钩子拦截到,因此就将该函数混入到了所有组件的created函数中。当应用越来越大、组件越来越多的时候,这个性能未免有点令人担忧;
持久性问题: 当URL的query部分越来越大的时候,超过了URL的长度限制,那么组件属性的持久性将会被中断。但我们并不能保证该长度不会超过,这随着应用的增长是无法预料的。在前端中,我们没有找到对应的库能进行定长加密解密,如果能找到,这个或将被解决;
安全性问题: 一直找不到比较安全的加密解密方式,而且我觉得这样做是会有安全隐患,但不知道究竟哪种场景会让这种安全性问题暴露的最大;
关于怎么在Vue中实现路由快照就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。