首頁  >  文章  >  微信小程式  >  小程式跨頁面互動的作用和方法

小程式跨頁面互動的作用和方法

hzc
hzc轉載
2020-06-10 17:05:132301瀏覽

去年年末,微信小程式的分包大小已經到達了12M 大小,一方面說明小程式的確逐步為開發者放開更大的權限,另一方面也說明了對於某些小程式8M的大小已經不夠用了。我個人今年也是在開發 to B 小程式應用程式。這裡列舉一些跨頁面互動的場景。

對於 B 端應用程式的業務需求來說,小程式開發的複雜度相對比網頁開發複雜一些。一個是雙執行緒的處理機制問題,另一個是頁面棧之間互動問題。

註: 筆者目前只需要開發微信小程序,為了在小程式頁面中可以使用 properties behaviors observers 等新功能,已經使用 Component 建構器來建構頁面。具體可以參考微信小程式 Component 建構器。如果你也沒有多端開發的需求,建議嘗試使用,可以得到不錯的體驗。

效能最佳化類別


對於小程式在頁面中點擊觸發wx.navigateTo 跳轉其他頁面,中間會有一段時間的空白加載期(對於分包出去的頁面,空白期則會更長),但是這是小程式內部機制,沒有辦法進行優化。我們只能眼睜睜的等待這段沒有意思的空白期過去。

當考慮到跳轉頁面後的第一件事情便是取數邏輯,那麼我們是否能夠進行最佳化呢?答案是肯定的。我們沒有辦法直接在當前頁面取得資料之後再進行跳轉操作(這樣操作更不好),但是我們卻可以利用快取當前的請求,詳情可以參考我之前的部落格文章 ——Promise物件 3 種妙用。

程式碼如下:

const promiseCache = new Map()

export function setCachePromise(key, promise) {
  promiseCache.set(key, promise)
}

export function getCachePromise(key) {
  // 根据key获取当前的数据  
  const promise = promiseCache.get(key)
  // 用完删除,目前只做中转用途,也可以添加其他用途
  promiseCache.delete(key)
  return promise  
}

做一份全域的Map,然後利用Map 快取promise 對象,在跳轉之前程式碼為:

// 导入 setCachePromise 函数

Component({
  methods: {
    getBookData(id) {
      const promise = // promise 请求
        setCachePromise(`xxx:${id}`, promise)      
    },  
    handleBookDetailShow(e) {
      const id = e.detail
      this.getBookData(id)
       wx.navigateTo({url: `xx/xx/x?id=${id}`})
    }
  }
})

而跳轉之後的程式碼也如下所示:

// 导入 getCachePromise 函数

Component({
    properties: {
      id: Number  
    },
    lifetimes: {
      attached () {
        const id = this.data.id  
        // 取得全局缓存的promise
        const bookPromise = getCachePromise(`xxx:${id}`)
        bookPromise.then((res) => {
          // 业务处理
        }).catch(error => {
          // 错误处理  
        })
      }
    },
    methods: {
      getBook() {
        // 获取数据,以便于 错误处理 上拉刷新 等操作  
      }  
    }
})

如此便可以同時處理取數和頁面載入的邏輯,當然,這個對於頁面有耦合性,不利於後續的刪除與修改。但考慮如果僅加在分包跳轉之間可能會有不錯的效果。

想要無侵入式,可以進一步學習研究 微信小程式之提高應用速度小技巧 以及 wxpage 框架,同時考慮到無論是ToC 還是ToC 用戶,都有可能存在硬體以及網路環境等問題,該優化還是非常值得的。

當然微信小程式為了減少冷啟動時間,提供了週期性更新 資料預拉取 功能。

註: 上面的 promiseCache 只作為中轉的用途,不作為緩存的用途,如果你考慮添加緩存,可以參考我之前的博客文章—— 前端 api 請求緩存方案。

通知類


如果是 pc 端中進行交互,對於資料的 CRUD。例如在詳情頁面進行了資料的修改和刪除,返回清單時候就直接調取先前儲存的清單查詢條件再次查詢即可,而對於行動端這種下拉滾動的設計,就沒有辦法直接呼叫先前的查詢條件來進行搜尋。

如果從清單頁面進入詳情頁面後,在詳情頁面只會進行新增或修改操作。然後返回列表頁面。此時可以提示使用者資料已經進行了修改,請使用者自行決定是否進行刷新操作。

如在編輯頁面修改了資料:

const app = getApp()

component({
  methods: {
    async handleSave() {
      //...
      app.globalData.xxxChanged = true
      //...  
    }
  }
})

清單介面:

const app = getApp()

component({
  pageLifetimes: {
    show() {
      this.confirmThenRefresh()
    }    
  },
  methods: {
    confirmThenRefresh() {
      // 检查 globalData,如果当前没有进行修改,直接返回 
      if(!app.globalData.xxxChanged) return
      wx.showModal({
        // ...
        complete: () => {
          // 无论确认刷新与否,都把数据置为 false 
          app.globalData.xxxChanged = false  
        }  
      })  
    }
  }  
})

當然了,我們也可以利用wx.setStorage 或getCurrentPage 來取得前面的頁面setData 來進行資料通知,以便使用者進行頁面重新整理。

訂閱發布類別


如果僅只涉及到修改資料的前提下,我們可以選擇讓使用者進行刷新操作,但是如果針對於刪除操作而言,如果用戶選擇不進行刷新,然後用戶又不小心點擊到了已經刪除的數據,就會發生錯誤。所以如果有刪除的需求,我們最好在返回清單頁面前就進行清單的修改,以免造成錯誤。

mitt

github 上有很多的pub/sub 開源函式庫,如果沒有特定的需求,找到程式碼量最少的就是 mitt這個庫了,作者是喜歡開發微型庫的 developit 大佬,著名的 preact 也是出於這位大佬之手。這裡就不做過多的介紹,非常簡單。大家可能都能看明白,程式碼如下(除去 flow 工具的檢查):

export default function mitt(all) {
  all = all || Object.create(null);

  return {
    on(type, handler) {
      (all[type] || (all[type] = [])).push(handler);
    },

    off(type, handler) {
      if (all[type]) {
        all[type].splice(all[type].indexOf(handler) >>> 0, 1);
      }
    },
    emit(type, evt) {
      (all[type] || []).slice().map((handler) => { handler(evt); });
      (all['*'] || []).slice().map((handler) => { handler(type, evt); });
    }
  };
}

僅僅只有3個方法,on emit以及 off。

只要在多個頁面匯入 產生的 mitt() 函數產生的物件即可(或直接放入 app.globalData 中也可)。

Component({
  lifetimes: {
    attached: function() {
      // 页面创建时执行
      const changeData = (type, data) => {
        // 处理传递过来的类型与数据
      }
      this._changed = changeData
      bus.on('xxxchanged', this._changed)
    },
    detached: function() {
      // 页面销毁时执行
      bus.off('xxxchanged', this._changed)
    }
  }
})

这里mitt可以有多个页面进行绑定事件,如果需求仅仅只涉及到两个页面之间,我们就可以使用 wx.navigateTo 中的 EventChannel (页面间事件信息通道)。可以参考微信小程序wx.navigateTo方法里的events参数使用详情及场景,该方案的利好在于,传递到下一个页面的参数也可以通过 EventChannel 来通知,以便于解决 properties 传递数据不宜过大的问题。

注: 一个页面展示很多信息的时候,会造成小程序页面的卡顿以及白屏。小程序官方也有长列表组件 recycle-view。有需求的情况下可以自行研究,这个不在这里详述。

鼓励一下

如果你觉得这篇文章不错,希望可以给与我一些鼓励,在我的 github 博客下帮忙 star 一下。
博客地址

推荐教程:《微信小程序

以上是小程式跨頁面互動的作用和方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除