微信小程序版本機(jī)制和storage如何平滑兼容詳解
問題背景
一款小程序默認(rèn)會有三個(gè)版本(開發(fā)、體驗(yàn)、生產(chǎn)),而同一臺手機(jī)打開同一個(gè)小程序只會對應(yīng)一份本地存儲(storage),這就會導(dǎo)致當(dāng)我們在本地存儲中記了某些信息時(shí),因?yàn)槭褂眠^不同版本的小程序,本地存儲就會出現(xiàn)不匹配或是被覆蓋的情況。為了解決這個(gè)問題,我們來設(shè)計(jì)一個(gè)可行的方案。
小程序版本
- 開發(fā)版
develop:本地預(yù)覽,本地真機(jī)調(diào)試 所對應(yīng)的小程序版本,只有在當(dāng)前開發(fā)者的設(shè)備上使用,一般都是開發(fā)階段調(diào)試功能一次性生成并使用。 - 體驗(yàn)版
trial:本地開發(fā)完成后,一般會上傳當(dāng)前版本至小程序后臺,小程序后臺會有對應(yīng)的版本記錄,可以將上傳的該版本設(shè)置成體驗(yàn)版,供有體驗(yàn)版權(quán)限的項(xiàng)目人員使用。 - 生產(chǎn)版
release:即發(fā)布后的線上版本,所有人可使用。
小程序的本地存儲
如果熟悉web的同學(xué),應(yīng)該很容易理解,小程序的本地存儲就和web本地存儲一樣,會有本地的 storage,具體 api 使用可以直接看官方文檔,存儲格式就是一個(gè) key 對應(yīng)一個(gè) value。就像上文背景中說到的,因?yàn)樾〕绦蛴卸鄠€(gè)版本,但是本地存儲一個(gè)小程序只會有一個(gè) storage,所以使用 api 去讀寫 storage 的時(shí)候,就沒法區(qū)分小程序版本,尤其是當(dāng)擁有體驗(yàn)版權(quán)限的項(xiàng)目人員,在第一次使用生產(chǎn)版本時(shí),會因?yàn)榇嬖谶^體驗(yàn)版的本地存儲而影響第一次打開正式版的體驗(yàn)效果。 下面我們就列一下可行的解決方案。
方案1:讀寫加標(biāo)志
因?yàn)?storage 的數(shù)據(jù)格式是 鍵值對 one key one value,那我們就可以在讀寫 storage 的時(shí)候都加上 版本 區(qū)分,這樣自然而然就鍵值就都分開了。
我簡單寫下大概的偽代碼
// 本地存儲鍵名map
const STORAGE_KEY_MAP = {
/** api環(huán)境 */
API_HOST: '__api_host__'
};
// 設(shè)置 開發(fā)版 字段
wx.setStorageSync(STORAGE_KEY_MAP.API_HOST + '@develop', 'dev1');
// 設(shè)置 體驗(yàn)版 字段
wx.setStorageSync(STORAGE_KEY_MAP.API_HOST + '@trial', 'dev1');
// 設(shè)置 生產(chǎn)版 字段(就不帶版本后綴了)
wx.setStorageSync(STORAGE_KEY_MAP.API_HOST , 'dev1');
// 讀取
wx.getStorageSync(STORAGE_KEY_MAP.API_HOST + '@develop');
wx.getStorageSync(STORAGE_KEY_MAP.API_HOST + '@trial');
wx.getStorageSync(STORAGE_KEY_MAP.API_HOST)通過給鍵名加上版本的標(biāo)志后,讀寫 storage 都不會再受版本的影響。這是最基礎(chǔ)最直接的一種方式,因?yàn)楸镜卮鎯Φ拇笮?0M,我們用????這個(gè)方法等于會同時(shí)存儲三個(gè)版本的本地存儲數(shù)據(jù),單純用這個(gè)方式上就會有些冗余的感覺了。為了更優(yōu)雅的使用本地存儲,我更推薦使用下面提供的第2種方案。
方案2:讀寫加標(biāo)志 + 監(jiān)測生產(chǎn)版本更新
這個(gè)方案不會影響生產(chǎn)版,上線后的小程序本地只會有一份數(shù)據(jù)。結(jié)合方案1,我們改進(jìn)的是,通過監(jiān)測生產(chǎn)版本更新,清空 storage。
解釋下是什么意思,因?yàn)橹饕?strong>體驗(yàn)版和生產(chǎn)版之間的 storage 會有影響,在一個(gè)小程序上線前,會有一批有體驗(yàn)權(quán)限的人,去試用此次即將上線的版本。當(dāng)這同一批人在發(fā)布后打開小程序,讀取 storage 就會是上次使用體驗(yàn)版存儲在本地的數(shù)據(jù)。為了將這兩個(gè)版本的 storage 隔離,我們就要使用 方案1,先將體驗(yàn)版的 storage 標(biāo)注出來,在生產(chǎn)版本發(fā)布后,打開生產(chǎn)版時(shí),將之前存儲的標(biāo)注為體驗(yàn)版的 storage 清除,這樣我們每個(gè)版本就只會存在一個(gè)版本的 storge 了(為什么呢?因?yàn)橄乱淮蔚捏w驗(yàn)版本,一定是基于上一個(gè)生產(chǎn)版而產(chǎn)生的,在上一個(gè)生產(chǎn)版本使用時(shí),我們已經(jīng)將之前的非生產(chǎn)版本 storage 已經(jīng)清楚了,那么使用新體驗(yàn)版時(shí),其實(shí)就回到了一個(gè)初始化的狀態(tài)了)。
使用這個(gè)方案在「開發(fā)->測試->發(fā)布」這一個(gè)正向的流程中是相對比較合理的,也就是每次發(fā)版后,非生產(chǎn)版本的小程序重新開始記錄本地存儲,
這里會有三個(gè)需要注意的地方,
- 小程序的更新機(jī)制:在冷啟動時(shí),即首次打開小程序,或者小程序超過30分鐘被自動銷毀后打開,都會默認(rèn)更新為最新版本的小程序(用戶無感)。在小程序還屬于熱啟動時(shí)(正在當(dāng)次使用中,沒有隱藏過前臺),是不會立刻主動下載新版本的,熱啟動期間想要更新小程序需通過「刪除小程序、重新進(jìn)入小程序」手動獲取最新版本的小程序。
- 小程序提供的監(jiān)聽版本管理的 api,即是讓我們在使用本地舊版本的時(shí)候感知到是否后臺有最新版本的發(fā)布。注意:非生產(chǎn)版本小程序沒有版本號的概念,無法使用版本更新監(jiān)聽,可以更改編譯模式設(shè)置模擬更新。
- 因?yàn)槲覀冃枰蹇辗巧a(chǎn)版本的
storage,所以我們在前期設(shè)置storage的時(shí)候,得將key統(tǒng)一維護(hù),這樣我們才能直接知道我們會設(shè)置進(jìn)storage的 Key Map,便于批量刪除。
下面我們來寫一下相關(guān)的實(shí)現(xiàn)
版本定義
// 版本
const APP_ENV_MAP = {
/** 開發(fā)版 */
develop: "develop",
/** 體驗(yàn)版 */
trial: "trial",
/** 生產(chǎn)版 */
release: "release",
};獲取當(dāng)前小程序版本
使用 api getAccountInfoSync 會返回小程序版本信息
// 獲取當(dāng)前小程序版本
function getEnvByAccountInfo() {
try {
const accountInfo = wx.getAccountInfoSync();
return accountInfo.miniProgram.envVersion; // 版本
} catch (error) {
return null;
}
}
// 當(dāng)前是否為生產(chǎn)版本
const IS_RELEASE = getEnvByAccountInfo() === APP_ENV_MAP.release;生產(chǎn)新版本監(jiān)測
使用 api getUpdateManager 管理小程序更新
STORAGE_KEY_MAP是維護(hù)好的 storage key map 集合,IS_RELEASE是判斷當(dāng)前版本是否為生產(chǎn)版小程序
// app.js
onLaunch: function () {
// 獲取小程序更新管理
const updateManager = wx.getUpdateManager();
// 監(jiān)聽是否有新版本
updateManager.onCheckForUpdate(function (res) {
// 所有體驗(yàn)版key
const allTrialKeys = Object.values(STORAGE_KEY_MAP).map((key) =>
getEnvStorageKey(key, APP_ENV_MAP.trial)
);
// 所有開發(fā)版key
const allDevKeys = Object.values(STORAGE_KEY_MAP).map((key) =>
getEnvStorageKey(key, APP_ENV_MAP.develop)
);
// 當(dāng)前是生產(chǎn)版且存在更(gèng)新的生產(chǎn)版本
if (IS_RELEASE && res.hasUpdate) {
// 沒有批量刪除的api,只能這么刪了
[...allTrialKeys, ...allDevKeys].forEach((key) => {
uni.removeStorageSync(key);
});
}
});
},整個(gè)過程大概就是這樣子
總結(jié)
到此這篇關(guān)于微信小程序版本機(jī)制和storage如何平滑兼容的文章就介紹到這了,更多相關(guān)小程序版本機(jī)制和storage平滑兼容內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript設(shè)計(jì)模式之裝飾者模式介紹
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之裝飾者模式介紹,通一個(gè)類來動態(tài)的對另一個(gè)類的功能對象進(jìn)行前或后的修飾,給它輔加一些額外的功能; 這是對一個(gè)類對象功能的裝飾,裝飾的類跟被裝飾的類,要求擁有相同的訪問接口方法(功能),需要的朋友可以參考下2014-12-12
純CSS3代碼實(shí)現(xiàn)滑動開關(guān)效果
CSS33D炫酷左右滑動開關(guān)按鈕是一款非??岬腃SS3 3D開關(guān)按鈕,點(diǎn)擊按鈕可以左右滑動,就像開關(guān)打開閉合一樣的效果,通過本篇文章給大家介紹純CSS3代碼實(shí)現(xiàn)滑動開關(guān)效果,需要的朋友可以參考下2015-08-08
基于JavaScript實(shí)現(xiàn)簡單的輪播圖
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)簡單的輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
javaScript讓文本框內(nèi)的最后一個(gè)文字的后面獲得焦點(diǎn)實(shí)現(xiàn)代碼
讓文本框內(nèi)的最后一個(gè)文字的后面獲得焦點(diǎn),在應(yīng)用中很常見,接下來提供解決方案,按興趣的朋友可以了解下2013-01-01
關(guān)于layui的動態(tài)圖標(biāo)不顯示的解決方法
今天小編就為大家分享一篇關(guān)于layui的動態(tài)圖標(biāo)不顯示的解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
找出字符串中出現(xiàn)次數(shù)最多的字母和出現(xiàn)次數(shù)精簡版
找出字符串中出現(xiàn)次數(shù)最多的字母和出現(xiàn)次數(shù)精簡版,有需求的朋友可以參考下2012-11-11
基于JavaScript實(shí)現(xiàn)本地圖片預(yù)覽
這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)本地圖片預(yù)覽的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02

