临近2021新年,公司想作个相似于支付宝年终报告的活动,经过在微信朋友圈分享、好友分享进行年终报告分享和拉新,整个项目中也遇到了一些问题,H5开发经验少,因此想把此次的经验总结下来.css
前提:这次活动使用的是有赞开源的基于 vue 的 Mobile 组件库,因为这次项目已经升级到了vue3.0,因此Vant也使用了V3版本.
在现有项目中使用 Vant 时,能够经过 npm 或 yarn 进行安装html
Vue 2 项目,安装 Vant 2: npm i vant -S Vue 3 项目,安装 Vant 3: npm i vant@next -S
引入组件 —>采用自动按需引入组件 (推荐)
babel-plugin-import 是一款 babel 插件,它会在编译过程当中将 import 的写法自动转换为按需引入的方式。
安装插件vue
npm i babel-plugin-import -D
// 对于使用 babel7 的用户,能够在 babel.config.js 中配置android
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 组件,插件会自动将代码转化为以上方式中的按需引入形式ios
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');
npm install autoprefixer postcss-pxtorem --save-dev
// postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem
// autoprefixer --浏览器前缀处理
配置:vue.config.js文件git
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中引入github
((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...web
2、接口报错netWork Errornpm
解决方式:下载Charles抓包工具,链接手机进行请求抓包,如上图,最终找到缘由是由于http和https混用致使的跨域问题,app端webview使用的协议与H5不一致,用老版本的app测试依然出现这个报错也是由于老版本的协议不一致,最终用户只能升级最新版才能避免这个问题,或者服务器须要作配置.canvas
// 去生成个人报告 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; } }
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); }); });
出现的问题:
找到的缘由: html2canvas插件在^1.0.0-rc.4版本以上有兼容问题,使用^1.0.0-rc.4版本正常 也有多是由于图片素材出现了跨域,若是是由于素材跨域,能够经过配置
导出的图片看起来没有原图那么清晰,这实际上是由于使用了背景图片的缘由。解决方法也很简单,就是直接使用<img>标签就行了,能够经过定位的方式进行样式处理.
若是使用PNG图片做为背景图,最后生成的图片却并不透明,可能会出现白边或白色角,这是由于生成canvas背景颜色默认为白色的缘故.解决方案就是增长一个背景颜色配置:
backgroundColor: "transparent"
<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; }); };