Vue如何实现关联页面多级跳转功能

小编给大家分享一下Vue如何实现关联页面多级跳转功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

背景

在项目开发过程中,经常会遇到从上一个页面跳转到下一个页面的需求,俗称 下钻 。比如在概览页面的数据,需要查看详情,点击某个图表或按钮,即可跳转到详情页面查看详情数据。

目前为止,我们的项目中还没有一个统一的页面跳转方法,实现页面跳转的方式也因人而异,并且现有的很多项目只能在两个页面之间来回跳转,基本没有完整的实现多个页面互相跳转的功能。

关联页面跳转做为项目的常用功能,并且执行的都是重复性高的代码逻辑,非常有必要把相关的逻辑抽出来,封装成简单易用的公共方法和公共组件。

目的

统一各个项目的关联跳转方法逻辑,封装成简单易用的公共组件。

方案设计

首先,分析一下关联页面跳转大概的逻辑步骤:

  1. 进入 页面 A ;

  2. 从 页面A 跳转到 页面 B ;

  3. 进入 页面 B ;

  4. 返回 页面 A ;

  5. 进入 页面 A ,即重新回到步骤 1 开始。

然后,对以上步骤进行细分:

  1. 假设步骤 1 是正常进入页面,这时候没有逻辑需要处理;

  2. 步骤 2 需要从 页面 A 跳转到 页面 B ,要实现这一步,就必需知道 页面 B 的路由地址,通过 VueRouter 跳转到 页面 B 的路由地址。并且如果 页面 B 需要的一些查询数据,就要把 页面 B 的数据保存起来,等到步骤 3 使用;

  3. 进入 页面B 后,如果要获取 页面 A 传过来的一些查询数据,就要先判断是不是从 页面 A 跳转过来的,如果是,就从保存数据的地方获取 页面 A 传过来的数据;

  4. 从 页面 B 返回 页面 A ,就必需知道 页面 A 的路由地址,通过 VueRouter 跳转到 页面 A 的路由地址。这里的路由地址,需要在步骤 2 跳转之前进行保存,这里才可以取到;

  5. 可以发现,步骤1和步骤5都是进入 页面 A ,但是执行的逻辑却不一样,所以, 页面 A 如果要恢复跳转到 页面 B 之前的一些数据,就要先判断是不是从 页面 B 跳转回来的,如果是,就从保存数据的地方获取跳转之前 页面 A 的数据;这里的跳转之前的数据,需要在步骤 2 跳转之前进行保存,这里才可以取到。

接下来,为了实现上述的逻辑,我们先确定用来保存 页面 A 和 页面 B 的数据的方法,这里采用的是 VUEX 。再梳理一下以上逻辑步骤,画出流程图。

流程图

源页面

Vue如何实现关联页面多级跳转功能

目标页面

Vue如何实现关联页面多级跳转功能

具体实现

源页面跳转到目标页面

这一步的逻辑写在 VUEX 中,每次需要进行这一步操作,直接调 VUEX 中对应的方法即可。具体实现逻辑,就是先把源页面和目标页面的标识添加到路由参数上(目的是为了区分当前页面是进行的目标页面还是返回的源页面),再保存源页面和目标页面的数据,然后进行路由跳转。

在 store.js 中添加两个以下两个变量:

tgtPageParams:{},//关联跳转的目标页面数据(只保留一项数据)
srcPageParams:[],//关联跳转的源页面数据(数组类型,保留多个页面的数据,可以多层返回,直到返回初始页面)

然后添加以下方法:

//关联跳转,跳转到目标页面,并保存源页面和目标页面的数据到Vuex
goTargetPage(state,options){
//在源页面的query添加tgtPageName标识,记住目标页面
options.srcParams.query=Object.assign({},options.srcParams.query,{tgtPageName:options.tgtParams.name});
//在目标页面的query添加srcPageName标识,记住源页面
options.tgtParams.query=Object.assign({},options.tgtParams.query,{srcPageName:options.srcParams.name});

state.srcPageParams.push(options.srcParams);//保存源页面数据
state.tgtPageParams=options.tgtParams;//保存目标页面数据

router.push({name:options.tgtParams.name,query:options.tgtParams.query});//跳转到目标页面
},

目标页面返回源页面

这一步的逻辑写在 VUEX 中,每次需要进行这一步操作,直接调 VUEX 中对应的方法即可。具体实现逻辑,就是从 state.srcPageParams 中取到源页面的数据(包括路由地址和参数),然后进行路由跳转。

在 VUEX 中添加以下方法:

//关联跳转,跳转回源页面
goSourcePage(state,vm){
letobj=state.srcPageParams.slice(-1)[0];//取数组的最后一项
//如果Vuex有上一页的数据,则根据Vuex的数据返回上一面
if(obj&&Object.keys(obj).length>0){
router.push({name:obj.name,query:obj.query});//进行跳转
}
//如果Vuex中没有上一页的数据,但是路由上有上一页的标志,则根据路由标志返回上一页(这是为了防止在详情页中刷新时,Vuex数据丢失,无法返回上一页的问题)
elseif(vm&&vm.$route.query.srcPageName){
router.push({name:vm.$route.query.srcPageName});
}
},

进入目标页面使用VUEX数据/返回源页面恢复VUEX数据

这一步的逻辑是把上面方案设计中的 步骤 3 和 步骤 5 合并起来了,写在公共函数文件中,每次需要进行这一步操作,直接调 Vue.prototype 中对应的方法即可。具体实现逻辑是:判断当前页面是源页面还是目标页面,如果是目标页面,那就使用源页面传过来的数据,如果是源页面,就恢复跳转之前的数据。

在公共函数文件 utils.js 中添加以下方法,并挂载到 Vue.prototype 上:

/**
*关联跳转相关的页面可以使用此方法
*1、源页面:可以把保存到Vuex中的数据恢复到data中使用
*2、目标页面:可以把源页面传递到Vuex中的数据放到data中使用
*3、源页面数据恢复后,删除Vuex中对应的备份数据,删除路由上保存的目标页标识
*@paramvm{object}必填当前Vue组件实例
*/
$changeVueData:(vm)=>{
lettgtParams=store.state.tgtPageParams;
letsrcParams=vm.$store.state.srcPageParams.slice(-1)[0]||{};//取最后一个元素值
letname=vm.$route.name;
letquery=vm.$deepCopyJSON(vm.$route.query);//这里深拷贝是因为$route.query需要更新

//判断当前页是目标页面还是源页面
//判断条件是先判断路由名是否一致,再判断指定的query的属性值是否也一致
letisTgtPage=tgtParams.name===name&&
(tgtParams.checkKeys?tgtParams.checkKeys.every(key=>tgtParams.query[key]===query[key]):true);
letisSrcPage=srcParams.name===name&&
(srcParams.checkKeys?srcParams.checkKeys.every(key=>srcParams.query[key]===query[key]):true);

//如果当前页面是目标页面
if(isTgtPage){
Object.assign(vm.$data,tgtParams.data||{});//将源页面传过来的数据更新到当前页面的data(),以便页面进行查询
}
//如果当前页面是源页面
if(isSrcPage){
Object.assign(vm.$data,srcParams.data||{});//跳转前保存的数据更新到当前页面的data(),以便页面进行还原
store.commit('popSourcePage');//将srcPageParams的最后一项数据删除
//源页面关联跳转逻辑结束后,清除掉当前页路由上的目标页标识,防止刷新页面有问题
deletequery.tgtPageName;
vm.$router.push({name,query});
}
},

返回上一页按钮

为了更方便的使用关联跳转功能,把返回上一页按钮封装成了一个组件,具体实现代码如下:

//back-button.vue
<template>
<buttonclass="primary-btnreturn-btn"v-if="showBackBtn"@click="backFn">
<iclass="return-icon"></i>{{backText}}
</button>
</template>
<script>
exportdefault{
name:'back-button',
props:{
//返回上一页的文字
backText:{
type:String,
default:()=>'上一步'
},
//返回上一页的函数
backFn:{
type:Function,
default:()=>{}
}
},
data(){
return{
showBackBtn:false,
};
},
mounted(){
this.setBackBtnShow();
},
activated(){
this.setBackBtnShow();
},
methods:{
//更新返回上一页按钮的状态
setBackBtnShow(){
this.$nextTick(()=>{
letsrcPage=this.$store.state.srcPageParams.slice(-1)[0];
this.showBackBtn=Boolean(srcPage&&Object.keys(srcPage).length>0);
});
},
},
};
</script>
<stylescopedlang="scss">
</style>

容错部分

考虑到关联跳转的过程中,有可能用户会突然中断,或者刷新页面等异常操作,设计了部分容错机制:

//根组件App.vue
/*...省略的代码...*/
watch:{
//监听,当路由发生变化的时候执行
$route(to,from){
//如果即不是源页面,也不是目标页面,则清空Vuex中保存的数据
//防止在关联跳转的过程中切换菜单或者进行其他操作,导致Vuex中有上一次关联跳转残留的数据
if(!to.query.srcPageName&&!to.query.tgtPageName){
this.$store.commit('clearTargetPage');
this.$store.commit('clearSourcePage');
}
},
},
/*...省略的代码...*/

使用示例

根据上述方案设计部分的步骤:

步骤 1 和步骤 5 ,进入 页面 A ,逻辑在同个页面,代码如下:

//页面A.vue
/*...省略的代码...*/
mounted(){
vm=this;
vm.$changeVueData(vm);//关联跳转相关页面,每次进入页面,必需执行$changeVueData函数,具体用法参考调用方法的注释

vm.ready();
},
/*...省略的代码...*/
步骤2,从页面A跳转到页面B,代码如下:

//页面A.vue
/*...省略的代码...*/
methods:{
//跳转到B页面
goUserSituation:function(name){
letsrcParams={
name:vm.$route.name,
query:vm.$route.query
};
lettgtParams={
name:'user-situation',
data:{
checkedSystem:name
}
};
vm.$goTargetPage(srcParams,tgtParams);
},
},
/*...省略的代码...*/

步骤 3,进入 页面 B ,代码如下:

//页面B.vue
/*...省略的代码...*/
mounted(){
vm=this;
vm.$changeVueData(vm);//关联跳转相关页面,每次进入页面,必需执行$changeVueData函数,具体用法参考调用方法的注释

vm.ready();
},
/*...省略的代码...*/
步骤4,返回页面A,代码如下:

//页面B.vue
/*...省略的代码...*/
<template>
<div>
<backButton:backFn="$goSourcePage"></backButton>
/*...省略的代码...*/
</div>
</template>
/*...省略的代码...*/

以上是“Vue如何实现关联页面多级跳转功能”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注恰卡编程网行业资讯频道!

发布于 2021-03-17 20:53:55
收藏
分享
海报
0 条评论
166
上一篇:python脚本打包后无法运行exe文件的解决方案 下一篇:DateTimeFormatter与SimpleDateFormat在Java8中有什么区别
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码