大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。
作者: qiuwww
web-view
加载 h5 与设置当前页面的小程序分享web-view 文档
web-view
与一般的 iframe 异同相似的地方:
web-view
是网页的原生载体,用于在原生环境中加载一个页面,iframe 是网页的 html 载体,用于在网页中加载一个新的动态资源。差异的地方
web-view
限制很严格:
web-view
加载的 url 需要在后台配置域名白名单,包括内部再次 iframe 内嵌的其他 url;
web-view
会自动铺满整个小程序页面,且默认展示到最上边一层,不能被覆盖;web-view
组件一定有原生导航栏,下面一定是全屏的 web-view
组件,navigationStyle: custom
对 web-view
组件无效。web-view
对象,也就是内外完全隔离,不能通过获取组件引用来操作;
web-view
网页只能 postMessage
给小程序,且小程序只能在特定时机(小程序后退、组件销毁、分享)触发并收到消息。也就是说,消息不是实时的,会存储到一个数组中在以上时机一起被拿到,web-view
发送的消息会一直累加,这个数组长度一直变大;bindload
,这个方法开发者工具无效,测试的时候发现,只要地址格式正确就认为是成功了,就会被触发,并不是页面加载完整才触发;binderror
,这个方法开发者工具无效,地址格式出错就认为加载失败,真正没加载出来也不会触发;web-view
加载 h5 页面web-view
组件,否则可能出现空白页;<template>
<view class="common-webview">
<web-view v-if="url" class="web" :src="url" @message="onWebMessage" />
</view>
</template>
@message
接受页面发出的消息,需要内嵌小程序引入微信的 sdk,然后使用wx.miniProgram.postMessage({ data: 'foo' })
来发消息;web-view
,内嵌 h5 需要打开小程序页面可以调用小程序的跳转方法进行跳转,这里注意 tab 页面只能使用wx.miniProgram.switchTab
,来跳转。(window as any).wx.miniProgram.navigateTo({
url: `/pages/common/webview?url=${encodeURIComponent(resolveH5Url)}`
});
web-view
页面的分享设置// 在h5中使用 wx.miniProgram.navigateTo
wx.navigateTo({
url: `/pages/common/webview?url=${encodeURIComponent(jumpUrl)}&imageUrl=${imageUrl}&title=${title}`
});
postMessage
的方式,将需要分享的参数动态的发给小程序页面,这样让小程序页面通过当前的 url 来匹配这里的 message 对象,从而拿到分享的信息,具体操作如下:// h5操作
if (env.inWechatMiniProgram) {
(window as any).wx.miniProgram.postMessage({
data: {
title: title || '', // 分享的title
imageUrl: imageUrl || '', // 分享的展示图片
pageUrl: window.location.href, // 当前页面的url,需要作为key来识别消息
}
});
}
// 小程序端
// 点击分享的时候,会调用两个函数,一个是onShareAppMessage,一个是onWebMessage(前)
// 接受postMsg的消息列表,进入页面或者点击操作的时候会发送消息,在小程序的分享按钮被点击的时候这里会被调用,调用在onShareAppMessage前
async onWebMessage({ detail: message }) {
this.messageList = message.data || [];
}
// 点击分享按钮,当前函数会被调用
async onShareAppMessage(options = {}) {
const { webViewUrl } = options;
const searchCurOptions = this.messageList.reverse().find(item => item.pageUrl === webViewUrl) || {};
console.log("这里就是当前分享的信息", searchCurOptions)
}
需要更多的配置,也是可以添加参数来实现的。
页面开发模式
可以通过设置 pages.json 中的页面的 navigationStyle 为 custom 来自定义导航栏。
web-view
页面无效;由于小程序只会在小程序页面间跳转的时候,默认标题栏出现返回按钮,所以如果在 tabbar 页面嵌入 h5,h5 内部的跳转是不能出现返回按钮的,所以需要特殊处理:
wx.miniProgram.navigateTo({
url: `/pages/common/webview?url=${encodeURIComponent(jumpUrl)}&imageUrl=${imageUrl}&title=${title}`
});
微信小程序分包
微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地的,这种策略可以缓解页面跳转时白屏的问题。同时微信还对小程序代码包大小设置了 2M (最初只有 1M)的上限来确保小程序能有还不错的启动速度。
uni-app 设置 condition
启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。
可以在不必将要开发的页面每次写到 pages.json 的 pages 下的第一个,也可以保证小程序每次刷新的时候,选择的编译模式能用。
{
"condition": {
"current": 0,
"list": [
{
"name": "index",
"path": "pages/index/index",
"query": "isShowHelp=1"
}
]
}
}
web-view
,可以打开 h5;official-account
组件关注关联的公众号;<script> // 小程序跳转小程序 wx.navigateToMiniProgram({ appId: appid, // 对方小程序的appid path: path, // 目标页面的地址,需要的参数可以直接拼写到后边,path 中 ? 后面的部分会成为 query extraData: { // 需要传递给目标小程序的数据 foo: 'bar' }, envVersion: 'release', // 要打开的小程序版本。仅在当前小程序为开发版或体验版时此参数有效。如果当前小程序是正式版,则打开的小程序必定是正式版。 success(res) { // 打开成功的后续操作,比如埋点什么的 // wxTelescope(baseKey + '-skip'); } }); </script>
<!-- h5跳转小程序 -->
<script> // 需要配置 wx.config({ openTagList: ['wx-open-launch-weapp'] }); </script>
<!-- 跳转按钮 -->
<wx-open-launch-weapp class="launch-btn" :username="tagUsername" :path="tagPath" @error="handleErrorFn" @launch="handleLaunchFn" >
<script type="text/wxtag-template"> <div style="padding: 10000px"> 跳转按钮 </div> </script>
</wx-open-launch-weapp>
小程序的运行机制
App.onLaunch
的回调参数一致。App.onLaunch
的回调参数一致,也就是与 wx.getLaunchOptionsSync 一致;// 设置channel,与一般的参数类似,可以通过修改小程序后台体验码来控制打开的参数,模拟渠道投放
// pages/index/index?channel=3UAKHCEV
// 获取当前的channel,可以针对不同的参数,做一些屏蔽或者替换操作
export const getChannel = () => {
const { query } = wx.getEnterOptionsSync();
const { channel } = query;
return channel;
};
小程序二维码 scene 参数限定长度为 32 位字符,但是实际开发中可能有很多的参数需要传递,比如pages/common/webview?url=https%3A%2F%2Fstatic.qa.91jkys.com%2Ff2e%2Fcustomer-h5-im%2F%23%2Fquick-ask%3FcurChannelInDisableList%3D0%26channel%3D27
,这个时候就需要通过特殊处理之后才能使用,常见方式如下:
// 调用
let options = wx.getEnterOptionsSync();
options = await queryLaunchParams(options);
// 方法定义:这里处理扫面二维码的时候,通过二维码的短参数获取存在数据库中的全部参数的操作
export const queryLaunchParams = async (options = {}) => {
if (options.scene) {
const { qrScene } = await store.dispatch('global/getParams', { destScene: options.scene });
return { ...options, ...queryString.parse(qrScene) };
} else {
return options;
}
};
web-view
打开 pdf 文件具体代码:
// 1. 这里要通过线上的地址去下载pdf,然后获取本地地址,之后再使用web-view打开
export const getDocumentLocalPath = (url = '') => {
const types = ['.pdf'];
const filterArr = types.filter(item => {
return url.includes(item);
});
if (filterArr.length < 1) {
return;
}
const fileType = filterArr[0];
return new Promise((resolve, reject) => {
wx.downloadFile({
url,
success: function(res) {
const filePath = res.tempFilePath;
console.log('getDocumentLocalPath', url, filePath);
wx.openDocument({
filePath: filePath,
fileType: fileType.slice(1),
success: function(res) {
// 使用pdf本地地址作为webview的地址,需要回退一下,不然就会有一个白页
uni.navigateBack({
delta: 1
});
resolve(filePath);
}
});
},
fail: function(e) {
reject(e);
}
});
});
};
// 2. 使用
const url = await getDocumentLocalPath(url);
// webview是可以打开本地生成的地址的
this.url = url;