uniapp嵌入h5辛励过程
前言
最近需要在原uniapp
开发的app
中嵌入h5
页面,过程遇到了非常多的问题,很有必要记录一下
按需引入vant
因为技术栈使用的是vue3
,所以使用unplugin-vue-components
完成按需引入,配置如下
// vue.config.js
const { defineConfig } = require("@vue/cli-service");
const { VantResolver } = require("unplugin-vue-components/resolvers");
const Components = require("unplugin-vue-components/webpack");
module.exports = defineConfig({
configureWebpack: {
plugins: [
Components({
resolvers: [VantResolver()],
}),
],
},
});
- 在使用组件时直接使用即可无需引入
- 消息类
Toast
、Dialog
等组件unplugin-vue-components
无法自动引入对应样式需手动引入
适配
适配采用postcss-px-to-viewport
,设计稿基准是750
,所以配置时需将viewportWidth
设置为750
,但vant
组件的基准是375
,所以适配需要对vant
进行兼容(2022了再手动计算就不合适了),所以适配如下
module.exports = ({ file }) => {
const designWidth =
file.includes("node_modules") && file.includes("vant") ? 375 : 750;
return {
plugins: {
"postcss-px-to-viewport": {
viewportWidth: designWidth,
},
},
};
};
vue3
- 模板
vue3
允许开发时模板不必被最外层元素包裹,但此种组件使用时无法添加class
等属性
- 路由
匹配不到路由时配置更新为
{
path: "/:pathMatch(.*)*",
name: "NotFound",
component: () => import("@/views/notFound"),
}
base
配置取消,通过createWebHistory
传入
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
hooks
qjd-ui-hooks
已无法直接在vue3
项目中直接使用,原因是找不到@vue/composition-api
,原项目使用的hooks
并非完全适用于vue3
app跳转h5
旧报告跳转后调用接口是免登录接口,由于无安全考虑方案被废弃,新报告需要考虑登录态,目前做的较为简单,通过中转页面在h5
设置cookie
,成功后后续接口携带cookie
即token
信息访问即可存在登录态 & 登录时效
方案一:
- 前端
app
调用后端接口获取shortKey
webview
页面嵌入服务端接口地址,shortKey
传给服务端- 服务端拿到
shortKey
后置换真正的token
- 获取到
token
后将其设置在h5
部署域名下
结果:
- 本地可以完成跳转,测试地址浏览器可以看到
cookie
- 后续真机测试时,
webview
指向地址需为真实页面地址,此方案放弃
方案二:
webview
页面嵌入h5
页面地址- 跳转
webview
前调用后端接口获取shortKey
- 获取
shortKey
后调用置换token
接口,并在服务端设置cookie
- 置换
token
接口成功后跳转webview
结果:
cookie
表现混乱,时有时无,怀疑和跨域有关,此方案放弃
方案三:
webview
页面嵌入h5
页面地址- 获取
shortKey
后将跳转webview
- 将
shortKey
等参数带给h5
页面 - 在
h5
中转页面调用置换token
接口,由服务端在此域名下设置cookie
- 在
h5
中转页面根据其他参数决定跳转哪个页面 - 在页面请求接口若
cookie
已经失效,则跳转无权限页面 - 由于页面层级深一层层返回体验较差,在无权限页面提供返回按钮,直接会到
app
结果:
- 真机表现较为正常,偶现
cookie
失效情况,需优化 app
有接口轮询,会在cookie
即将过期时更新cookie
,则导致h5
cookie过期时,回到app
时app
登录时效依然ok,表现不一,需优化- 后续微信消息跳转报告时此套逻辑不在适用,要走微信授权登录,需重新开发
h5向uni通信
由于需在无权限页提供一键返回按钮,需要h5
向uniapp
发送消息,uniapp
文档不明朗,有误导倾向
- 误区一
文档中@meaasge
的表述如下:
H5 暂不支持(可以直接使用 window.postMessage (opens new window))
此处H5
指的是uniapp
打包为H5
,并非指在webview
中嵌入的h5
页面,所以在webview
中嵌入的h5
页面向uniapp
发送消息时仍调用uni.postMessage
而非window.postMessage
- 误区二
文档中关于demo
部分调用了如下方法
document.addEventListener('UniAppJSBridgeReady', function() {})
此方法是监听uni
是否已经注入,但此方法应是在初始化时调用,而对于更深层次的调用时无需使用该方法监听,可以直接使用uni
或者初始化时调用该方法后注册一个全局变量,后续使用即可
综上,完成h5向uni通信
如下:
- 引入
uni
<!-- 有条件可以将资源down下来放在本地 -->
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
- 调用
uni
// 返回
const backHandle = () => {
uni && uni.postMessage({
data: {
type: "back",
},
});
};
uni分享pdf
uniapp
提供几种分享方式,大致两种
- 调用社区
sdk
- 调用手机自带分享
uniapp
集成的sdk
目前支持微信、QQ、微博
,这远不够目前要求的平台,如:钉钉、企业微信等平台需要自行实现,插件市场倒是可以找到插件,但是数量都只有一个,不但收费,而且质量、版本无保障,退而求其次,选择手机自带的分享功能
- 安卓
文档解释安卓高版本无法分享图片,若是携带图片,则默认为图片类型,此种效果不是我们想要的
- ios
强!!!
结论:
- 采用手机自带分享功能
- 分享时区分
ios
和安卓
,ios
分享携带图片,安卓
分享只有文案和链接
注: 分享出去的效果由机型确定,所以在测试华为分享微信时是真的丑
分享链接
原采用pc
端pdf
下载链接,但是由于content-type
是错误的导致在钉钉上打开乱码,所以采用新的链接
新链接具备时效性,目前时效为1
天,此链接具备一定安全性
ios安全区
对于新的ios
手机如:iphone11、iphone12、iphonex等机型都有底部安全区,也就是底部白色区域,处理方案是添加viewport-fit=cover
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui,viewport-fit=cover" />
在h5
上是没有什么问题的,基本可以解决问题,但是在uni
中,表现不尽如人意,经过尝试去掉
body {
height: 100%;
}
后,凡是撑开body
产生滚动条的页面不会产生底部白条,而其余页面偶现,暂无更好方案处理
样式变化后带来后续的滚动计算方式
ios齐刘海、底部黑条
完整样式如下,没有此样式,底部区域会被黑条覆盖
@supports ((height: constant(safe-area-inset-top)) or (height: env(safe-area-inset-top))) and (-webkit-overflow-scrolling: touch) {
body {
/* 适配齐刘海 */
padding-top: constant(safe-area-inset-top);
padding-top: env(safe-area-inset-top);
/* 适配底部小黑条 */
padding-bottom: costant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
iphonex兼容
图片写了宽度后,高度会自适应,但是在iphonex
机型下不写高度会出现图片拉长情况
特性环境测试问题
pc
端服务端通过不同请求头拉取不同资源,移动端真机测试无法设置
uniapp
真机模式提供了useragent
配置,可以添加多余信息,配置如下
"app-plus" : {
"useragent": {
"value": "(#test#)",
"concatenate": true // 开启concatenate在原useragent上添加信息
},
"useragent_android": {
"value": "(#test#)",
"concatenate": true
},
"useragent_ios": {
"value": "(#test#)",
"concatenate": true
},
}
此种方式为静态配置,经测试服务端可以拿到配置的额外配置的(#test#)
数据
可以后续改进方案通过setUserAgent
动态设置useragent
,如下
const userAgent = plus.navigator.getUserAgent();
plus.navigator.setUserAgent(userAgent + '(#test#)')
结语
移动端问题真心多
转载自:https://juejin.cn/post/7125354973713399821