wenaox 離線狀態管理

輕量小程序 state 管理 lib,對戶外探險的 offline 場景特別友好。比 Redux / MobX 對小程序適合,比裸寫 setData 有結構。

為什麼選它

戶外探險的 多日離線行程設計 三層架構需要:

  1. 本地狀態樹(行程、團員、操作記錄)
  2. outbox queue(離線寫入 → 上線同步)
  3. 衝突解決策略

裸用 wx.setStorage() 太低階,用 redux 對小程序又重——wenaox 是中間派

  • 輕量(< 50 KB)
  • 原生 reactive(state 變化自動觸發 setData)
  • middleware 機制(可塞 outbox 同步邏輯)
  • 不依賴 React/Vue 概念,純小程序

GitHub

https://github.com/zhangkun-Jser/wenaox

三層離線架構對應

多日離線行程設計wenaox 解法
層 1:純讀取wenaox state 從本地 storage 載入;UI 直接綁 state
層 2:本地操作每個操作 dispatch action → 寫進 state.outbox 陣列
層 3:批次同步監聽網路恢復事件,middleware 把 outbox 一筆筆送

戶外探險旅遊小程序核心功能清單 的支援

功能wenaox 角色
#5 行程公告出發前 fetch 進 state,行中讀本地
#7 SOS(離線觸發)dispatch 寫 outbox + 緊急 flag,上線優先送
#8 離線地圖 / 軌跡GPS 點寫 state.gps_track[],回程 batch upload
#9 活動相簿拍照 metadata 寫 state.photos[],影像本身存檔案系統
#10 簽到簽到記錄寫 state.checkins[],離線 OK

簡化使用範例

// store.js
import { createStore } from "wenaox";
 
const store = createStore({
  state: {
    trips: [],          // 出團清單(出發前 fetch)
    outbox: [],         // 離線操作隊列
    user: null,
  },
  mutations: {
    addToOutbox(state, op) {
      state.outbox.push({
        ...op,
        id: generateUuid(),
        timestamp: Date.now(),
        synced: false,
      });
    },
    markSynced(state, id) {
      const op = state.outbox.find(o => o.id === id);
      if (op) op.synced = true;
    },
  },
  actions: {
    async syncOutbox({ state, commit }) {
      const pending = state.outbox.filter(o => !o.synced);
      for (const op of pending) {
        try {
          await sendToServer(op);
          commit("markSynced", op.id);
        } catch (e) {
          // 留在 outbox,下次重試
          break;
        }
      }
    },
  },
});
 
export default store;

衝突解決策略

戶外場景的 last-write-wins 通常夠用——客人在現場做的就是真相。但要注意:

  • timestamp 用本地時間(GPS 對時也行,但成本高)
  • 同步前標 conflict_with 欄位讓 server 端能審計
  • 重要決定(取消預訂等)要走特殊路徑,不放 outbox

安裝

npm i wenaox

反模式

❌ 把整個 outbox 一次送出(萬一失敗很慘)→ 逐筆送、單筆失敗就 break ❌ outbox 沒上限(buffer 爆滿)→ 加 100/500 上限,超過提示使用者 ❌ 不存 UUID(server 端去重困難)→ 永遠加 UUID ❌ 同步阻塞 UI → 用 async middleware,背景跑

v2 才用

MVP 階段不需要 wenaox——v1 的功能(出團列表、報名、行前確認)都不需要離線寫入。wenaox 是進入 v2 做 SOS / 離線地圖 / 相簿時才導入

替代選項

選項為什麼可能不選
裸 setData + storageOK 但隨成長會變難維護
Redux對小程序太重(dispatch flow + middleware overhead)
MobX (we-mobx)reactive 一樣,但小程序生態 wenaox 更原生
Vuex要走 uni-app(微信小程序框架選擇 不選)

相關概念

強連結(戶外探險專屬)

深入閱讀(外部資源)

← 回到 wiki