详解小程序中h5页面onShow实现及跨页面通信方案(2)

<web-view wx:if="https://www.jb51.net/{{url}}" src="https://www.jb51.net/{{url}}" binderror="onError" bindload="onLoaded" bindmessage="onPostMessage"></web-view> // 链接处理工具方法 import util from '@/lib/util'; // 全局数据存储操作类 import routeParams from '@/lib/routeParams'; const urlReg = /^(https?\:\/\/[^?#]+)(\?[^#]*)?(#[^\?&]+)?(.+)?$/; let messageData = {}; export default class extends wepy.page { data = { // 页面展示次数 pageShowCount: 0, // 页面url中query部分的参数对象 mQuery: {}, ... } onShow(){ ++this.pageShowCount; // 获取其他页面经过操作后,需要传递给h5的参数 let data = routeParams.getBackFromData() || {}; // webview页面状态更新 if(this.pageShowCount > 1 && this.mQuery.__isonshowpro && this.mQuery.__isonshowpro === '1' || data.refresh){ // 获取需要传递给h5页面的参数 let refreshParam = data.refreshParam; ... // 如果连接中带有需要处理onShow逻辑的参数(通过url的hash和h5交互,而不是刷页面) if (this.pageShowCount > 1 && this.mQuery.__isonshowpro === '1') { let [whole, mainUrl, queryStr, hashStr, hashQueryStr] = urlReg.exec(this.url); // 在url的hash中加入新的参数 hashStr = (hashStr || '#').substring(1); if (refreshParam) { delete refreshParam.refresh; } const messageData = this.getNavigateMessageData(); // 将需要更新的参数传给页面hash hashStr = util.addQuery(hashStr, Object.assign({ // onshow标志位 __isonshow: 1, // wa主动触发hashchange标志位 // 其实目前通过__isonshow就可以判断是wa主动触发hashchange // 设置该字段是为了明确功能,且以后扩展用 __wachangehash: 1, // 时间戳刷新 __hashtimestamp: Date.now() }, messageData, refreshParam)); this.url = mainUrl + queryStr + '#' + hashStr; console.log('【webview-hashchange-url】', this.url); // 这里要加个延迟,否则在webview返回到webview时,无法触发hashchange,应该是小程序bug setTimeout(()=> { this.$apply(); }, 50); // 通过修改query参数,刷新webview } else { ... } ... } } /** * 获取需要发送的消息数据 */ getNavigateMessageData(){ let rst = {}; for(let i in messageData){ /* message结构: message: { key: 'xx', // 消息名称 content: 'xx', // 消息内容 trigger: { // 触发条件 type: '', // 触发类型 - immediately 在下一次onshow或者打开页面中立刻触发, - url 在找到指定h5链接时触发 content: '' // 条件内容 - type=immediately 时为空 - type=url 时候为h5链接地址 } } */ const message = messageData[i]; const trigger = message.trigger || {}; // 立刻发送、路径触发 if(trigger.type === 'immediately' || trigger.type === 'url' && this.url.indexOf(trigger.content) > -1){ // 将key和content集合到一个对象中,便于hash直接设置 rst[message.key] = message.content; // 消息通知后,从缓存中删除 delete messageData[message.key]; } } console.log('【webview-get-message】', rst); console.log('【webview-message-cache】', messageData); return rst; } /** * 存储消息数据 */ storeNavigateMessageData(message){ if(message && message.key){ console.log('【webview-store-message】', message) // 通过key设置每一条消息名称 messageData[message.key] = message; console.log('【webview-message-cache】', messageData); } } methods = { // 接收发送过来的消息 onPostMessage(e){ if(!e.detail.data)return; const detailData = e.detail.data; // 获取消息数据 let messageData = getValueFromMixedArray(detailData, 'messageData', true); if (messageData) { // 存储 this.storeNavigateMessageData(messageData); } ... } } ... }

上面东西看着挺多,总结下来就是几点:

绑定bindmessage事件

接收到页面传来的消息之后,需要按照一定规则存起来(我是按照key存储的)

webview在触发onShow钩子时候,按照之前传过来的触发条件(condition),取出需要发送的消息数据

将数据拼接到url的hash部分,并加入特有的标志位,重新加载url

h5端

h5端在做修改时也要考虑几点:

最好能把这些交互逻辑封装起来

让业务方比较简单方便的调用

这里我新定义了2个方法

onShow(callback)

描述:这个和小程序onShow钩子一样,只不过是给h5调用的

参数:callback 回调方法

例子:发布页面,需要选择分类,返回时需要更新分类信息

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/6644dc59318e6781fa936b8f11b244ed.html