likes
comments
collection
share

uniapp嵌入h5辛励过程

作者站长头像
站长
· 阅读数 21

前言

最近需要在原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()],
      }),
    ],
  },
});
  1. 在使用组件时直接使用即可无需引入
  2. 消息类ToastDialog等组件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,成功后后续接口携带cookietoken信息访问即可存在登录态 & 登录时效

方案一:

  1. 前端app调用后端接口获取shortKey
  2. webview页面嵌入服务端接口地址,shortKey传给服务端
  3. 服务端拿到shortKey后置换真正的token
  4. 获取到token后将其设置在h5部署域名下

结果:

  1. 本地可以完成跳转,测试地址浏览器可以看到cookie
  2. 后续真机测试时,webview指向地址需为真实页面地址,此方案放弃

方案二:

  1. webview页面嵌入h5页面地址
  2. 跳转webview前调用后端接口获取shortKey
  3. 获取shortKey后调用置换token接口,并在服务端设置cookie
  4. 置换token接口成功后跳转webview

结果:

cookie表现混乱,时有时无,怀疑和跨域有关,此方案放弃

方案三:

  1. webview页面嵌入h5页面地址
  2. 获取shortKey后将跳转webview
  3. shortKey等参数带给h5页面
  4. h5中转页面调用置换token接口,由服务端在此域名下设置cookie
  5. h5中转页面根据其他参数决定跳转哪个页面
  6. 在页面请求接口若cookie已经失效,则跳转无权限页面
  7. 由于页面层级深一层层返回体验较差,在无权限页面提供返回按钮,直接会到app

结果:

  1. 真机表现较为正常,偶现cookie失效情况,需优化
  2. app有接口轮询,会在cookie即将过期时更新cookie,则导致h5cookie过期时,回到appapp登录时效依然ok,表现不一,需优化
  3. 后续微信消息跳转报告时此套逻辑不在适用,要走微信授权登录,需重新开发

h5向uni通信

由于需在无权限页提供一键返回按钮,需要h5uniapp发送消息,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通信如下:

  1. 引入uni
<!-- 有条件可以将资源down下来放在本地 -->
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
  1. 调用uni
// 返回
const backHandle = () => {
  uni && uni.postMessage({
    data: {
      type: "back",
    },
  });
};

uni分享pdf

uniapp提供几种分享方式,大致两种

  1. 调用社区sdk
  2. 调用手机自带分享

uniapp集成的sdk目前支持微信、QQ、微博,这远不够目前要求的平台,如:钉钉、企业微信等平台需要自行实现,插件市场倒是可以找到插件,但是数量都只有一个,不但收费,而且质量、版本无保障,退而求其次,选择手机自带的分享功能

  • 安卓

文档解释安卓高版本无法分享图片,若是携带图片,则默认为图片类型,此种效果不是我们想要的

  • ios

强!!!

结论:

  1. 采用手机自带分享功能
  2. 分享时区分ios安卓ios分享携带图片,安卓分享只有文案和链接

注: 分享出去的效果由机型确定,所以在测试华为分享微信时是真的丑

分享链接

原采用pcpdf下载链接,但是由于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#)')

结语

移动端问题真心多