臨近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; }); };