問題背景 — 分享的資料來源
當前在維護的小程式專案使用wepy開發;分享的資料都是通過介面請求後臺的形式獲得;然後存在了資料data的物件中;類似
定義分享資料
data = {
shareData: "", // 分享資料
}
獲取分享資料
tip.getShareDataReci(res => {
that.shareData = res; // 賦值後臺返回的分享資料
that.$apply();
}, curCode); // curCode當前商品的唯一code值
使用分享資料
onShareAppMessage(res) {
let that = this;
if (res.from === "button") {
// 來自頁面內轉發按鈕
}
return {
title: that.shareData.title,
imageUrl: that.shareData.img,
path: that.shareData.path,
success: function(res) {
...
}
}
問題的發生
在大部分的電商網站都有類似的情況;在一個商品List中點選進入某一個商品詳情A;然後在詳情A的頁面中又會有推薦的商品;這個時間點選進入商品詳情B;點選分享(不區分右上角…分享和自己新增的分享按鈕);分享的資料是自己存data裡面的資料;也都是對的;關鍵的操作來了;這個時候返回商品A(不區分右滑返回和左上角返回鍵和物理返回鍵);點選分享;會發現分享的資料仍然是商品B的資訊~
問題的解決
1. 出棧的解決方式
在商品詳情A的推薦位置;點選的時候使用redirect
出棧的方式去開啟詳情B;這個時候分享B是正確的;然後返回是不會到A的;因為被解除安裝了;直接從B回到了List;不會存在回到A之後分享資料不正確的問題~~
但是這樣的解決方案帶來的體驗是不好的
2. 快取讀取的方式解決(目前在用的)
2.1 存 — 將code存快取
第一步在商品List跳轉到商品詳情A的時候;在A的onluad週期中(返回不會觸發該週期)進行儲存唯一code值
的動作
let reciCodeList = wepy.getStorageSync("reciCodeList"); // 定義獲取的code集合
if (!reciCodeList.length) {
// 如果之前沒有code則往新的陣列中新增該code
wepy.setStorageSync("reciCodeList", [].concat(options.dishCode));
} else {
// 如果之前有code(可能在詳情A的推薦位置又進入了詳情B;類推)
// 會進行一個去重的動作;防止出現兩個一樣的
let i = utils.inArray(options.dishCode, reciCodeList);
if (i >= 0) {
shareData.splice(i, 1);
}
// 將可能進行去重處理過的資料存快取
wepy.setStorageSync("reciCodeList",reciCodeList.concat(options.dishCode));
}
2.2 改 — 修改code集合
第二步在商品詳情A的onUnload週期中(頁面返回動作會觸發該生命週期;頁面出棧也會觸發到)進行修改reciCodeList
動作;此動作是為了能在返回之後拿到正確的code值
onUnload() {
// 先獲取儲存的code集合
let reciCodeList = wepy.getStorageSync("reciCodeList");
// 刪除陣列的最後一項(為了能在返回之後的頁面拿最後一項即為當前正確項)
/* 我是一個栗子
在經過onluad以後會得到
在A的時候;存下了A的唯一code值;為reciCodeList = [`A`];
在B的時候;累計存下了B的唯一code值;為reciCodeList = [`A`,`B`];
在C的時候;累計存下了B的唯一code值;為reciCodeList = [`A`,`B`,`C`];
...
當觸發返回的時候;會觸發onUnload函式;這個時候去刪除最後一下;會得到
在C的時候;儲存的reciCodeList = [`A`,`B`,`C`];
這個時候去返回;並且刪除最後一項;得到了
reciCodeList = [`A`,`B`]; 並且頁面回到了B的頁面
*/
reciCodeList.pop();
// 儲存新的集合
wepy.setStorageSync("reciCodeList", reciCodeList);
}
2.3 取 — 取到正確的code
第三步在商品詳情A的onShow週期中(每次頁面被顯示都會觸發;返回也是被顯示了)進行獲取分享資料的動作
async onShow() {
let that = this;
// 先獲取儲存的code集合
let reciCodeList = wepy.getStorageSync("reciCodeList");
if (reciCodeList.length) {
// 如果存在code值;則拿最後一個code值為當前code值
let curCode = reciCodeList[reciCodeList.length - 1];
// 當前值去傳送請求;獲得正確的分享資料
tip.getShareDataReci(res => {
that.shareData = res;
that.$apply();
}, curCode);
}
}
問題的延伸
可能會出現類似的問題;例如當前詳情的分享+收藏+不同使用者展示不用資訊(下有栗子);都存在返回後資料不正確的情況;也可以一併使用這個方案處理
// 我是不同使用者展示不用資訊的栗子
// 依然使用前文的 A B C (詳情頁都有登入的入口)
A頁面是未登入狀態;顯示未登入狀態該有的展示資訊;不在A頁面登入;點選推薦位置到B頁面
B頁面起初顯示的也是未登入狀態下的展示資訊;這個時候在B頁面進行了登入;回到A還是未登入的狀態
這個時候只需要在A的onShow取一次快取的使用者資訊即可
that.userInfo = wepy.getStorageSync("userInfo");
這個是目前微信存在的bug;可先通過方法規避開;等微信修復了以後就樂呵呵了~~~