需求分析:
一、在项目实现总的列表页-详情页返回不刷新;
二、总的列表页中加了筛选条件,经过筛选后进入筛选结果页,然后点击筛选结果页中的任意一种商品到详情页后再返回到筛选结果页,对刚刚的筛选结果进行缓存,不会刷新。
作为一个vue的小白,对于解决这样的问题首先想到的是去一些搜索引擎上找找各路大神的关于这方面的经验,发现各个需求不尽相同,同时也不能很好地针对性的解决自己遇到的这个问题,在和老师的指导下进行了长达9天的讨论,最终将此问题得以解决,接下来为大家展示我们所做的工作:
1、vue利用keep-alive/beforeRouteLeave,keep——Alive的缓存功能
在vue中默认router-link进入每一个页面的组件都是不会进行缓存的,为了解决这个问题,我们可以使用keep-Alive来缓存来提高性能,达到我们的需求
在app.vue中进行如下的更改:
将 <router-view></router-view>更改至如下的字段:
<keep-alive>
<router-view v-if="$route.meta.keepAlive" >
this.$router.push({name:'goodsList',params:{form:this.form}})
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" ></router-view>
然后在index.js中对于需要缓存的路由meta中加上keepAlive:true的要求,如下
{
path: 'goodsList',
name: 'goodsList',
component: goodsList,
meta: {
title: '列表',
keepAlive: true,
need_log: false
}
},
2、利用beforeRouteLeave动态决定要不要缓存刷新。
首先先对beforeRouteLeave这种相关钩子函数进行介绍 :
vue组件内部有三种导航卫士:
1)beforeRouteEnter
2)beforeRouteUpdate (2.2 新增)
3)beforeRouteLeave
由字面意思可知——beforeRouteLeave就是离开该页面时出发的卫士,也正是我们所需要的
beforeRouteLeave的三个参数分别是:to 是指要去的页面;
from 指的是本页面地址;
next 是指的是下一步操作;
这个离开守卫钩子函数一般用来禁止用户在还未保存修改前就突然离开的尴尬局面,该导航可以通过next取消。
//钩子函数的具体使用案例
beforeRouteLeave (to, from, next) {
if (to.name == "goodsList") {
to.meta.keepAlive = true;
}
next();
},
利用路由的beforeRouteLeave,如果跳出去的页面是需要返回不刷新页面的路由(正如本项目所需到的筛选结果页),那么就给当前的meta.keepAlive=true,否则置为false
//下面这个函数其中to表示下一个要进入的路由。form表示当前页面路由。next()表示执行跳转。
beforeRouteLeave (to, from, next) {
if (to.name == "goodsDetail") {
from.meta.keepAlive = true;
console.log("这是list列表里的if语句")
} else if (to.name == "goodsList_blank") {//此处是假的一个空白页来进行二次刷新,文章最后会有对其介绍及代码的书写
console.log('into goodsList_blank' + from.meta.keepAlive);
} else {
from.meta.keepAlive = false;
}
next();
},
当时想的没那么复杂,以为需要缓存的时候就走keepAlive的true的view,再回来就会缓存不刷新了。但是这个问题虽然解决了,但在测试的过程中又遇到了另一个大的问题挡住了任务进度的进行:从总的商品列表页到详情页再返回到总的商品列表页这个问题得到了解决,但是当输入筛选条件后,按流程进入到筛选结果页,筛选结果出现,点击详情后,返回,就直接蹦到了总的商品列表页(我们的总的商品列表页与筛选结果页是同一个url),这个问题就很恶心,意思就是说目前他只能缓存一个页面,然后以后所有的操作都是返回的之前缓存的页面,有点儿郁闷。
之前看到的文章里介绍了利用go(0)进行页面重进一次,可是由于同一个url的原因,页面重进的时候还是总的那个商品列表页;在自己参考大神的相关解答时,发现了可以加上个空白页来承接以下keepAlive为false的情况,相当于利用blank页面达到go(0),让页面冲金的目的,体验又不会刷新,由于是空页面,所以几乎看不出问题:
1)keep-alive的应用,修改meta;
2)beforeRouteLeave钩子函数的利用
3)blank.vue的代码填充
3、利用blank进行处理
<template>
<div></div>
</template>
<script>
export default {
name: "blank",
data() {
return {
};
},
methods: {
initPage()
{
this.$router.push({ name: 'goodsList', params:this.$route.params})
}
},
created() {
this.initPage();
},
}
</script>
<style scoped>
</style>
created()调用this.initpage的方法,blank只是重进一下goodslist这个列表页
4、在list.vue添加具体的逻辑进行判断
beforeRouteLeave (to, from, next) {
if (to.name == "goodsDetail") {
from.meta.keepAlive = true;
console.log("这是list列表里的if语句")
} else if (to.name == "goodsList_blank") {
console.log('into goodsList_blank' + from.meta.keepAlive);
} else {
from.meta.keepAlive = false;
}
next();
},
activated(){
this.getAllData();
},
methods: {
getAllData()
{
console.log(this.$route.params)
if(this.$route.params.form){
this.pageType = 'search'
}
this.getListData(); //获取产品列表
//判断如果keepAlive是false那就修改为True,再重载一下
if(!this.$route.meta.keepAlive)
{
this.$route.meta.keepAlive = true;
if(this.$route.params.form){
this.$router.push({ name: 'goodsList_blank', params:this.$route.params})
}else {
this.$router.go(0)
}
}
},
5、同时,在detail.vue中同样也添加一个钩子函数,
在详情页返回到筛选结果页的时候起作用,具体代码实现如下:
beforeRouteLeave (to, from, next) {
if (to.name == "goodsList") {
to.meta.keepAlive = true;
console.log("dsafdsafdsafdsagreaghjsag")
}
next();
},
6、在search.vue中添加一个钩子函数
商品的详情页返回到goodsList,同时在搜索设置中同时也是搜索条件输入后也会跳到goodsList
beforeRouteLeave (to, from, next) {
if (to.name == "goodsList") {
to.meta.keepAlive = false;
console.log("nihaoa1ssssssssssssssssssss")
}
next();
},
以上就是我解决这个需求的具体步骤,可能与你的需求大致相同,但是具体的还得每个人针对自己的项目自己进行书写,希望我的这个解决过程能够帮到每一个需要的人!