Vue实现前进/后退控制缓存/刷新 |
您所在的位置:网站首页 › vue路由后退为啥直接退出了应用 › Vue实现前进/后退控制缓存/刷新 |
引子
PC端需求,下钻层级较多,且均为列表页。列表进入到新建页面,新建成功则返回上一页并刷新页面,编辑/新建页面直接点击返回则返回上一页页面的缓存状态。 方案 hack手法 this.$router.push({ path: '/product', query: { t: +new Date() } })此方法虽然简单,但是有明显缺陷: 丑; 前进刷新,浏览器回退的上一页url上有时间戳,但是面包屑上点击跳转无时间戳只能刷新,除非维护页面的时间戳。 meta路由depth层级 // router-view页面 // router.js meta: { keepAlive: true, deepth: x // 路由层级1,2,...n }监听$route维护include数组,下钻则添加当前页name(此name为.vue里的name)到数组里,回退则去除。 此方法缺陷为: 兼容性差,逻辑推演太复杂:同模块跨级跳转;不同下钻的模块间跳转。 路由文件需要静态配置一堆depth Vuex此方案适用于React框架。将表格查询的Filter信息存储起来,回退时用Filter查询列表,若回退想回到第一页,可跳转前修改Vuex的信息再跳转。 此方案缺陷: 不是真缓存,存在接口请求和重新渲染; 页面如果有多个接口请求,包含数据看板、多列表,存储变复杂; 滚动位置。 keepAlive刷新方案 多页面会用到router,但不一定用到vuex,那么方案如下:EventBus; 监听$route变化; activated; 刷新有两个方案: Html标签上添加v-if,改变成false再改回true; keepAlive标签上添加include、exclude。利用exclude优先于include,include初始值为router里所有meta为keepAlive的name集合(此name为.vue里的name,router配置的name规范成和.vue保持一致方便初始化),需要刷新时将刷新页面的name值push进exclude数组,渲染完再移除,逻辑比维护include数组简单很多。第一个方案更通用,当前页刷新也可以使用,可以用在点击侧边栏刷新(当前页没变化不会出发$route变化和activated);第二个方案缺陷是无法刷新当前页,但使用了keepAlive自带方法更优雅。 data() { return { keepAliveReload: true, exclude: [] } }, created() { this.keepAliveReloadInit = Object.assign({}, this._data) if (!this.$eventBus._events['keepAliveReload']) { this.$eventBus.$on('keepAliveReload', () => { this.keepAliveReload = false this.$nextTick(() => { Object.assign(this, this.keepAliveReloadInit) }) }) } }, watch: { $route: function(to, from) { if (to.meta.keepAlive && to.meta.reload) { this.exclude.push(to.name) this.$nextTick(() => { this.exclude.pop() Object.assign(this, this.keepAliveReloadInit) }) to.meta.reload = false to.meta.loaded = true } } } 刷新参数携带方案meta元信息; params; // 方案1 this.$route.meta.reload = true this.$router.push('/pointExchange/accountDetail') // router守卫传递reload信息 router.beforeEach((to, from, next) => { to.meta.reload = from.meta.reload from.meta.reload = false }) // 方案2 this.$router.push({ name: 'accountDetail', params: { reload: true } }) 方案2有些缺陷: 潜在的与路由配置path/:reload冲突; 只能使用name跳转params参数才能设置成功。方案1好处是不限制$router是path还是name跳转,且meta元信息冲突的可能性更低。 总结最终方案为: keepAlive缓存,在keepAlive标签上v-if,include/exclude实现刷新,通信为$route监听、EventBus(用来侧边栏刷新,见方案),刷新标识通过meta元信息传递实现。 此方案我认为通用性最高(无需vuex、多页面有router),逻辑简单,实现也不复杂。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |