困扰了一年多的问题。。。我在微信官方论坛,思否都提问过。
https://developers.weixin.qq.com/community/develop/doc/000808a4ae80c0f76b9961ef051c00?jumpto=comment&commentid=000ce8c3e74d10176f9923d8d56c
https://segmentfault.com/q/1010000021256867
订单列表页,头部是tab切换,可以下拉翻页。每条数据都有不同行为的按钮操作。
比如:
待支付的订单,按钮(取消订单,去支付)
已完成的订单,按钮(去评论/查看评论,再次预订,删除订单)
假如:
我此刻点击 “待支付”选项下》第2页的》第5条数据,进入详情页(详情页的按钮和它的列表页按钮一致)》点击了“去支付”按钮
返回列表页,想要仍然在“待支付”选项下,第二页的第5条数据的位置上,但是这条数据已经移除了,因为该条数据已经是“已支付”状态了
或者说,我在列表页“全部”选项下,下拉到第3页,第5条,点击了一条“已完成”的订单,点击“去评论”,然后进入“评论页”》“提交”,返回列表页,仍然在“全部”选项下的,第3页,第5条的位置上,该数据已变为“已评论”的状态,按钮从“去评论”变更为“查看评论”
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
因为“下单”,“删除订单”,“去评论”,“去支付”,好多操作都会影响订单列表,为了每次都能得到最新的状态,所以我现在订单列表页用了onshow方法,导致每次列表页,都重新请求第1页数据,并且手动scrollTop=0。这样就导致我无法还原进入详情页之前的位置。有没有局部刷新的方法啊?既能更新某一条的数据,又能保存当前page和当前scrolltop位置。
看到了zangeci的回答,很感谢!针对他提出的两种方法,我都回去研究了一下。现在给大家分享一下,这两种方式都是怎么实现的。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1. 先说状态管理全局数据的这个方法:
前提:all 是全部订单,pending是待支付 unuse是待使用, refund是退款售后
【订单列表页】
onShow(){ //每次onshow的时候,显示保存为全局的最新状态的list
let data=this.$store.state.orderList;
this.noResult=data.list.length==0 ?true :false;
if(data.cur=='pending'){ //新创建订单,返回到列表页,要重新读取数据
this.cur=data.cur;//全部列表里点击“再来一单”
this.getList(true);
}
},
async getList(first){//订单列表
let list=[];
if (first) {
this.current_page =1;
}else {
list =this.list;
}
this.isLoading=true;
const loginResult =await get('order/index', {
category:this.cur,
page:this.current_page
})
if (loginResult.code==200) {
let data=loginResult.data;
this.total_page=data.total_page;
if(first){
this.list=data.list;
this.noResult=data.list.length==0 ?true :false;
this.$store.dispatch('saveOrderListFn',{ //保存全局list列表和当前tab值
cur:this.cur,
list:data.list
});
}else{
this.list=list.concat(data.list);
this.$store.dispatch('saveOrderListFn',{ //保存全局list列表和当前tab值
cur:this.cur,
list:list.concat(data.list)
});
}
}
},
updateNew(stateName,state,type,order_id){ //更新某个订单,列表页中的,删除订单,取消订单,都在本页面完成,需要调用updateNew
console.log('update');
let data=this.$store.state.orderList;
if(data.list.length>0){
let aa=data.list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(data.cur=='all'){//全部 : 其他操作都是改变list中这一条的状态
data.list[aa].show_status=stateName;
data.list[aa].status=state;
if(type=='del'){ //全部列表中: ‘删除订单’是删除list中的某一条
data.list.splice(aa,1);
}
}else if(data.cur=='pending') {//待支付: '取消订单' ‘去支付’ 这两个操作,都是删除list中的这条
data.list.splice(aa,1);
}else if(data.cur=='unuse') {//待使用 : '申请退款'>删除list中的这条
data.list.splice(aa,1);
}else if(data.cur=='refund') {//退款 '再来一单'
}
this.list=data.list;
this.$store.dispatch('saveOrderListFn',data);
}
}
},
【订单详情页】【支付页】【申请退款页】同理,都是操作之后要更新全局list数据。
【当然了,订单详情页的状态,也要做一个全局的状态存储,因为在订单详情页,点击“去支付”,支付成功后返回订单详情页,订单详情也要变为“待使用”,再返回到订单列表,订单列表这条也要变为待使用】
【订单详情页】
onShow(){//如果是从申请退款,支付页回来//重新赋值,因为有操作
let {theOrder}=this.$store.state;
if(theOrder.hasOwnProperty('order_id')){
this.obj=theOrder;
}
},
updateNew(stateName,state,type,isGoBack){//更新订单列表中这个订单
let {orderList,theOrder}=this.$store.state;
if(orderList.list.length>0){
let aa=orderList.list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(orderList.cur=='all'){//全部 ‘删除订单’,取消订单
orderList.list[aa].show_status=stateName;
orderList.list[aa].status=state;
if(type=='del'){
orderList.list.splice(aa,1);
}
}else if(orderList.cur=='pending') {//待支付 '取消订单' ‘去支付’
orderList.list.splice(aa,1);
}else if(orderList.cur=='unuse') {//可使用 '申请退款'>删除
orderList.list.splice(aa,1);
}else if(orderList.cur=='refund') {//退款 '再来一单'
}
this.$store.dispatch('saveOrderListFn',orderList); //更新全局订单列表list
}
}
if(theOrder.hasOwnProperty('order_id') && theOrder.order_id==order_id){ // 这段是支付页的,【订单详情】和【申请退款】页,这段需要对应修改逻辑!!!!!!!!!
if(type=='pay'){
theOrder.show_status='待使用';
theOrder.status='2';
}else if(type=='cancel'){
theOrder.show_status='已取消';
theOrder.status='-1';
}
this.$store.dispatch('saveTheOrderFn',theOrder); //更新全局,这条订单详情的状态
}
},
订单列表,订单详情,支付,申请退款,下单,所有页面按照这个更新全局订单list和当前订单info的思想,完成所有按钮操作逻辑之后
这个效果基本就完成了。
每次订单列表和订单详情onshow的时候,都显示保存在全局状态里的最新状态
这个效果测试过,暂时没发现啥问题
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2.全局事件监听和取消监听,也叫事件订阅和取消订阅
需要安装一个迷你版(~ 500b)的事件订阅和发布的库,简单实用。
https://github.com/hustcc/onfire.js/blob/master/README_zh.md
npm i --save onfire.js
如何使用,参考https://www.jianshu.com/p/35a778c7467d
【订单列表】
onShow(){
let that=this;
this.$fire.on("refundOrder", function(order_id) {//触发退款
let {list,cur}=that;
let aa=list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(cur=='all'){//全部 ‘删除订单’
list[aa].show_status='退款中';
list[aa].status='-3';
}else if(cur=='unuse') {//可使用 '申请退款'>删除
list.splice(aa,1);
}
that.list=list;
that.noResult=list.length==0 ?true :false;
}
});
this.$fire.on("payOrder", function(order_id) {//触发支付订单
let {list,cur}=that;
let aa=list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(cur=='all'){//全部 ‘删除订单’
list[aa].show_status='待使用';
list[aa].status='2';
}else if(cur=='pending') {//待支付 '取消订单' ‘去支付’
list.splice(aa,1);
}
that.list=list;
that.noResult=list.length==0 ?true :false;
}
});
this.$fire.on("cancelOrder", function(order_id) {//触发取消订单
let {list,cur}=that;
let aa=list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(cur=='all'){//全部 ‘删除订单’
list[aa].show_status='已取消';
list[aa].status='-1';
}else if(cur=='pending') {//待支付
list.splice(aa,1);
}
that.list=list;
that.noResult=list.length==0 ?true :false;
}
});
this.$fire.on("delOrder", function(order_id) { //触发删除订单
let {list,cur}=that;
let aa=list.findIndex(n=>{
return n.order_id==order_id
})
if(aa!=-1){
if(cur=='all'){//全部 ‘删除订单’
list.splice(aa,1);
}
that.list=list;
that.noResult=list.length==0 ?true :false;
}
});
this.$fire.on("addOrder", function(order_id) {//触发新建订单
that.cur='pending';//全部列表里点击“再来一单”
that.getList(true);
});
},
onUnload(){ //取消监听事件
this.$fire.off("refundOrder");
this.$fire.off("payOrder");
this.$fire.off("cancelOrder");
this.$fire.off("addOrder");
},
【订单详情】【支付页】【退款页】【下单页】按钮操作之后,要触发事件:
拿【订单详情页】,"取消订单"举例,其他的都同理
async cancelOrder(way){//取消订单
const loginResult =await get('order/cancel', {
order_id:order_id,
})
if (loginResult.code==200) {
let data=loginResult.data;
this.obj.show_status='已取消';
this.obj.status='-1';
this.$fire.fire("cancelOrder",order_id);
}
},
【当然了,订单详情也需要监听支付,退款等操作,在返回的时候,订单详情也要相应变更状态,和订单列表同理】
【订单详情页】
onShow(){ //如果是从申请退款,支付倒计时结束,回来 //重新赋值,因为有操作
this.$fire.on("refundOrder", function(data) {//从申请退款页返回
that.obj.show_status='退款中';
that.obj.status='-3';
});
this.$fire.on("payOrder", function(data) {//从支付页,支付返回
that.obj.show_status='待使用';
that.obj.status='2';
});
this.$fire.on("cancelOrder", function(data) {//从支付页,倒计时结束返回
that.obj.show_status='已取消';
that.obj.status='-1';
});
},
onUnload(){ //取消事件监听
this.$fire.off("refundOrder");
this.$fire.off("payOrder");
this.$fire.off("cancelOrder");
},
这个效果基本完成了,简单的测试了下,还没有大量测,暂没有发现问题。
如果大家发现了什么问题,留言交流吧