临近2021新年,公司想做个类似于支付宝年终报告的活动,通过在微信朋友圈分享、好友分享进行年终报告分享和拉新,整个项目中也遇到了一些问题,H5开发经验少,所以想把这次的经验总结下来.

一、移动端适配问题

前提:此次活动使用的是有赞开源的基于 vue 的 Mobile 组件库,由于此次项目已经升级到了vue3.0,所以Vant也使用了V3版本.
在现有项目中使用 Vant 时,可以通过 npm 或 yarn 进行安装

Vue 2 项目,安装 Vant 2:
npm i vant -S 
Vue 3 项目,安装 Vant 3:
npm i vant@next -S

引入组件 —>采用自动按需引入组件 (推荐)
babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。
安装插件

 npm i babel-plugin-import -D

// 对于使用 babel7 的用户,可以在 babel.config.js 中配置

module.exports = {
    presets: ['@vue/cli-plugin-babel/preset'],
    plugins: [['import', {
        libraryName: 'vant',
        libraryDirectory: 'es',
        // style: true,
        style: (name) = >`$ {
            name
        }
        /style/less`,
    },
    'vant', ], ],
};

// 接着在main.js中直接引入 Vant 组件,插件会自动将代码转化为以上方式中的按需引入形式

import { Button } from 'vant’;
const app = createApp(App);
// vant 挂载
const vantArr = [
NavBar, Tabbar, TabbarItem, Button, Toast, Step, Steps, Form, Picker, Field, Popup, ShareSheet, Swipe, SwipeItem, Overlay, Dialog, Loading, Checkbox];
vantArr.filter((e) => app.use(e));
app.use(Lazyload, {
lazyComponent: true,
});
app.mount('#app');
如何结合autoprefixer、postcss-pxtorem做移动端适配?
npm install autoprefixer postcss-pxtorem --save-dev

// postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem
// autoprefixer --浏览器前缀处理
配置:vue.config.js文件

const autoprefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
module.exports = {
css: {
loaderOptions: {
postcss: {
plugins: [
autoprefixer(),
pxtorem({
// 设计稿 375->37.5
// 设计稿:750->75,Vant 是基于 375
rootValue: 75,
propList: ['\*'],
// 该项仅在使用 Circle 组件时需要
// 原因参见 https://github.com/youzan/vant/issues/1948
selectorBlackList: ['van-‘] // 排除vant框架相关组件
})
]
}
}
}
}
经过以上配置,小屏手机下字体依然过大,导致字体和图片有重叠或遮挡,如何处理?

新建rem.js,在main.js中引入

((doc, win) => {

// 用原生方法获取用户设置的浏览器的字体大小(兼容ie)
let userWebsetFont;

if (doc.documentElement.currentStyle) {

userWebsetFont = doc.documentElement.currentStyle.fontSize;

} else {

userWebsetFont = getComputedStyle(doc.documentElement, false).fontSize;

}
// 取整后与默认16px的比例系数
const xs = parseFloat(userWebsetFont) / 16;

// 设置rem的js设置的字体大小
let viewJssetFont; let resultFont;

const docEl = doc.documentElement;

const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';

const { clientWidth, clientHeight } = docEl;

const recalc = () => {

if (!clientWidth) return;

if (!doc.addEventListener) return;

if (clientWidth >= 750) {

docEl.style.fontSize = '75px';

} else if (clientHeight <= 480) {

docEl.style.fontSize = '28px';

} else if (clientHeight < 625) {

docEl.style.fontSize = '34px';

} else {

// 设置rem的js设置的字体大小
viewJssetFont = 75 \* (clientWidth / 750);

// 最终的字体大小为rem字体/系数
resultFont = viewJssetFont / xs;

// 设置根字体大小
docEl.style.fontSize = `${resultFont}px`;

}
};
win.addEventListener(resizeEvt, recalc, false);

doc.addEventListener('DOMContentLoaded', recalc, false);

})(document, window);

import './utils/rem';
这里有网友总结的比较全的适配案:https://www.cnblogs.com/axl23...

二、接口报错netWork Error

解决方式:下载Charles抓包工具,连接手机进行请求抓包,如上图,最终找到原因是因为http和https混用导致的跨域问题,app端webview使用的协议与H5不一致,用老版本的app测试依然出现这个报错也是因为老版本的协议不一致,最终用户只能升级最新版才能避免这个问题,或者服务器需要做配置.

三、H5唤起app方法

// 去生成我的报告
const onCreateMyReport = () => {
// 判断是不是微信浏览器
const ua = navigator.userAgent;
const isWeixin = ua.indexOf('MicroMessenger') !== -1;
const isAndroid = ua\.indexOf\('Android'\) \> \-1 \|\| ua\.indexOf\('Adr'\) \> \-1; // android终端
const isiOS = !!ua.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); // ios终端

if (isWeixin && isAndroid) {
// 安卓端微信,跳转到空白页面唤起app
window.location.href = 'https://www.51trust.com/mobile/html/ywxAwake.html';
} else {
// iOS终 端直接页面跳转,ios的schema链接和下载链接是一致的
window.location.href = 'https://www.51trust.com/download/';

}
};

在am项目新建一个awakenApp.html,部署后是https://www.51trust.com/mobil...
// 唤醒app

function loadURL() {
const androidrl = 'yiwangxin://51trust/main';
const downLoadUrl = 'https://www.51trust.com/download/';

let iFrame;
const u = navigator.userAgent;
const isWeixin = u.indexOf('MicroMessenger') !== -1;
const isAndroid = u\.indexOf\('Android'\) \> \-1 \|\| u\.indexOf\('Adr'\) \> \-1; // android终端
console.log('isAndroid--', isAndroid);

if (isAndroid) {

// 安卓终端使用iframe
iFrame = document.createElement('iframe');
iFrame.setAttribute('src', androidrl);
iFrame.setAttribute('style', 'display:none;');
iFrame.setAttribute('height', '0px');
iFrame.setAttribute('width', '0px');
iFrame.setAttribute('frameborder', '0');
document.body.appendChild(iFrame);
// 发起请求后这个 iFrame 就没用了,所以把它从 dom 上移除掉
setTimeout(() => {
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
}, 100);

if(!isWeixin){
window.location = downLoadUrl;
}
} else {
window.location = downLoadUrl;
}
}

四、canvas生成图片,使用html2canvas遇到的坑

html2canvas ——> HTML代码转换成Canvas,进而生成可保存分享的图片

npm install --save html2canvas

在使用的页面引入

import html2canvas from 'html2canvas’
<div :ref="setImageDown" id="imageDown" class="shareImg-box”>XXXX</div>

const setCanvas = () => new Promise((resolve) => {
const canvasDom = imageDown.value;
html2canvas(canvasDom, {
  backgroundColor: 'transparent',
  width: canvasDom.offsetWidth, // 设置canvas尺寸与所截图尺寸相同,防止白边
  height: canvasDom.offsetHeight, // 防止白边
  useCORS: true,
  logging: true,
}).then((canvas) => {
   const url = canvas.toDataURL('image/png', 2.0);
   resolve(url);
}).catch((err) => { console.log(err); });
});

出现的问题:

1、html2canvas在IOS端生成图片不显示?
  找到的原因: html2canvas插件在^1.0.0-rc.4版本以上有兼容问题,使用^1.0.0-rc.4版本正常
  也有可能是因为图片素材出现了跨域,如果是因为素材跨域,可以通过配置 
2、生成的图片模糊?
  导出的图片看起来没有原图那么清晰,这其实是因为使用了背景图片的原因。解决方法也很简单,就是直接使用<img>标签就好了,可以通过定位的方式进行样式处理.
3、PNG图片不透明问题?

如果使用PNG图片作为背景图,最后生成的图片却并不透明,可能会出现白边或白色角,这是因为生成canvas背景颜色默认为白色的缘故.解决方案就是增加一个背景颜色配置:

backgroundColor: "transparent"

五、当input输入内容超过input可视框,再次聚焦时,如何把光标定位自动定位到文本最后?

<input id="feedBack-input" class="feedBack-input" v-model="feedbackval" placeholder="请输入" @click="End">

const End = () => { // input获取光标显示在最后
nextTick(() => {
   const { length } = state.feedbackval;
   const elInput = document.getElementById('feedBack-input');
   elInput.focus();
   elInput.selectionStart = length;
   elInput.selectionEnd = length;
  });
};

Cristina_Guan
45 声望0 粉丝

引用和评论

0 条评论