時(shí)間過(guò)去了兩個(gè)多月,2024已經(jīng)到來(lái),又老了一歲。頭發(fā)也掉了好多。在這兩個(gè)月時(shí)間里都忙著寫頁(yè)面,感覺(jué)時(shí)間過(guò)去得很快。沒(méi)有以前那么輕松了。也不是遇到了什么難點(diǎn)技術(shù),而是接手了一個(gè)很爛得項(xiàng)目。能有多爛,一個(gè)頁(yè)面發(fā)起六次同一個(gè)請(qǐng)求得存在,不得已又要重構(gòu)頁(yè)面。最近呢,在做webapp,h5,小程序,釘釘?shù)眠m配,都是用一套代碼??梢哉f(shuō)都是h5鏈接得形式引入。無(wú)非顯示東西不一樣,這個(gè)不一樣得東西,一般都是頭部,跟下面得導(dǎo)航欄顯示,功能得適配。不同手機(jī)機(jī)型得適配,也無(wú)非兩種機(jī)型,安卓,IOS,線上問(wèn)題得調(diào)試,還有屏幕尺寸得適配。不得不說(shuō)這些真的掉頭發(fā)。這篇主要是h5嵌入小程序,以及app適配方案。
說(shuō)明
本文是針對(duì)是把h5應(yīng)用嵌入其它平臺(tái)得流程。不是單獨(dú)taro發(fā)布一個(gè)小程序,單獨(dú)打包成app得流程,是從一個(gè)主平臺(tái)直接進(jìn)入一個(gè)子系統(tǒng)得嵌入適配方案。所以描述得時(shí)候需要注意理解,我們是做了單點(diǎn)登錄得。直接是使用一套 “build:h5”: “taro build --type h5”,進(jìn)行得方案。當(dāng)然不同得單獨(dú)做登錄得時(shí)候無(wú)法就是taro去獲取當(dāng)前得環(huán)境是weapp還是h5。我們得單點(diǎn)登錄采用得方案是憑借在url里面得環(huán)境判斷也是通過(guò)url方式。不是cooike跨域共享。這是因?yàn)槠脚_(tái)很早就有的了。所以需要注意理解。不過(guò)這篇主要講得是h5嵌入小程序
一、h5嵌入小程序適配流程
1、H5項(xiàng)目編譯?;谧约旱腶pp項(xiàng)目,仍編譯成h5環(huán)境的代碼,就不存在啟動(dòng)weapp的情況了。換句話說(shuō),就是都用h5頁(yè)面了。
2、照文檔進(jìn)行適配。根據(jù)本文第二點(diǎn)和第三點(diǎn)所述,代碼層面做評(píng)估適配開(kāi)發(fā)。
3、選擇性使用sdk。如項(xiàng)目中不涉及文件類(上傳下載)操作,適配工作可至本文第三點(diǎn)第4點(diǎn)即可;如涉及,請(qǐng)按照三.5描述進(jìn)行sdk引入適配。
4、發(fā)布更新測(cè)試調(diào)試。同app,項(xiàng)目正常部署后,生成的h5地址就是最終通過(guò)平臺(tái)小程序嵌入的h5地址,更新完成后,進(jìn)行集成聯(lián)調(diào);但有一點(diǎn)和app不同,h5地址必須是映射過(guò)的,否則小程序集成環(huán)境無(wú)法正常訪問(wèn)。
二、 頁(yè)面結(jié)構(gòu)適配
1.導(dǎo)航欄:
思想上,app是需要導(dǎo)航欄得,小程序是自帶固定得導(dǎo)航欄得。當(dāng)是小程序時(shí)去除頭部導(dǎo)航欄,頂部欄不能有任何東西,小程序的webview固定了導(dǎo)航欄,只允許修改基礎(chǔ)配置,背景色,標(biāo)題等。記得每個(gè)頁(yè)面都要改,建議添加全局的判斷方法.。所以這時(shí)候封裝導(dǎo)航欄時(shí),這時(shí)候就要考慮環(huán)境了。
2.頁(yè)面內(nèi)容得適配:
總體思想,采用媒體查詢?yōu)榛鶞?zhǔn),大得調(diào)整(有些頁(yè)面在一些尺寸得屏幕需要另外得展示),頁(yè)面區(qū)間采用flex布局。
因?yàn)槲覀兪褂玫檬莟aro,在 Taro 中尺寸單位建議使用 px、 百分比 %,Taro 默認(rèn)會(huì)對(duì)所有
單位進(jìn)行轉(zhuǎn)換。在 Taro 中書寫尺寸按照 1:1 的關(guān)系來(lái)進(jìn)行書寫,即從設(shè)計(jì)稿上量的長(zhǎng)度 100px,那么尺寸書寫就是 100px,當(dāng)轉(zhuǎn)成微信小程序的時(shí)候,尺寸將默認(rèn)轉(zhuǎn)換為 100rpx,當(dāng)轉(zhuǎn)成 H5 時(shí)將默認(rèn)轉(zhuǎn)換為以 rem 為單位的值。
3.路由切換:
盡量采用路由跳轉(zhuǎn),為什么內(nèi),如果采用tabs進(jìn)行切換時(shí)候,如果時(shí)app返回操作還能進(jìn)行處理,如果是微信小程序,上面返回就直接讓你退出了。為此我們還進(jìn)行了重構(gòu)了首頁(yè)頁(yè)面。同時(shí)也要考慮手機(jī)物理按鍵得返回。所以盡量采用路由跳轉(zhuǎn)方式。
4.js操作像素時(shí):
當(dāng)我們用js進(jìn)行像素操作時(shí),對(duì)此我們需要封裝一個(gè)方法進(jìn)行轉(zhuǎn)化,特殊處理只用關(guān)心px。
export const transformToRemOrRpx = function(size: number): Promise<string> {
return new Promise((resolve, reject) => {
Taro.getSystemInfo({
success: res => {
const width = res.windowWidth;
const pixelRatio = 750 / width;
let transSize = "0";
if (process.env.TARO_ENV === 'weapp') {
transSize = size * pixelRatio + "rpx";
} else {
let baseSize = width >= 640 ? 40 : width <= 320 ? 20 : width / 320 * 20;
transSize = size / baseSize + "rem";
}
resolve(transSize);
},
fail: err => {
reject(err);
}
})
})
}
三、功能實(shí)現(xiàn):
1. 編譯
當(dāng)前就不存在編譯成weapp的情況了,都是h5,所以需要從跳轉(zhuǎn)的地址欄上區(qū)分是小程序的h5還是app的h5,需要通過(guò)環(huán)境進(jìn)行判斷。以及根據(jù)這個(gè)判斷來(lái)做適配。
注意:獲取地址欄參數(shù)需要用原生location方式取,taro自帶的api有可能會(huì)取不到,如果你想偷懶,本文也提供了獲取地址欄參數(shù)的辦法。
//解析url參數(shù)
export function parseUrlSearch<T>(): T {
if (!window.location) { return {} as any }
let href = window.location.href;
if (href.includes('#') && href.includes('?')) {
let queryIndex = href.indexOf('?')
let symbolIndex = href.indexOf('#')
let symbolList = href.split('#')
symbolList = symbolList.filter(o => o.includes('?') ? o : false)
let moreQuery = symbolList[1] && symbolList[1].slice(symbolList[1].indexOf('?')) || '';
if (queryIndex < symbolIndex) {
let hrefString = href.slice(0, href.indexOf('#'))
href = hrefString + moreQuery.replace('?', '&')
}
}
let qindex = href.indexOf("?");
let queryParams = href.substr(qindex + 1);
let queryParamsArr = queryParams.split("&");
let queryParamsObj = {};
queryParamsArr.map((v) => {
let tmp = v.split("=");
let value: string = tmp.length === 2 ? decodeURIComponent(tmp[1]) : '';
if (value.includes("[") && value.includes("]")) {
queryParamsObj[tmp[0]] = JSON.parse(decodeURIComponent(value));
} else {
queryParamsObj[tmp[0]] = decodeURIComponent(tmp[1])
}
});
return queryParamsObj as any;
}
2. 數(shù)據(jù)獲取(緩存)
小程序的h5,即webview場(chǎng)景下微信不允許使用緩存,需要適配;另外taro提供的存儲(chǔ)api無(wú)法支持跨頁(yè)面存儲(chǔ)。小程序的h5所需全局?jǐn)?shù)據(jù),必須全部采用從地址欄傳參方式獲取,拿不到。
3. Token校驗(yàn)
微信嵌h5環(huán)境下,系統(tǒng)要求去除token校驗(yàn),或者采用調(diào)組件庫(kù)內(nèi)app.ts中提供的token更新接口方式進(jìn)行token校驗(yàn)更新。因?yàn)樾〕绦虻膚ebview里頭注入基礎(chǔ)平臺(tái)的js文件會(huì)有很多問(wèn)題,最主要的是域名校驗(yàn)和資源路徑問(wèn)題,當(dāng)前解決起來(lái)成本比較高,所以先去除。
4. taro全局路徑配置(接口根路徑、打包靜態(tài)資源路徑)
const path = require("path");
const config = {
projectName: 'myApp',
date: '2024-1-20',
designWidth: 750,
deviceRatio: {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2
},
sourceRoot: 'src',
outputRoot: `dist/${process.env.TARO_ENV}`,//多端開(kāi)發(fā)時(shí)必須使用******important*******
plugins: [],
defineConstants: {},
copy: {
patterns: [
{
from: '',
to: ''
},
],
options: {}
},
framework: 'react',
mini: {
postcss: {
pxtransform: {
enable: true,
config: {}
},
url: {
enable: true,
config: {
limit: 1024 // 設(shè)定轉(zhuǎn)換尺寸上限
}
},
cssModules: {
enable: true, // 默認(rèn)為 false,如需使用 css modules 功能,則設(shè)為 true
config: {
namingPattern: 'module', // 轉(zhuǎn)換模式,取值為 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
},
h5: {
publicPath: '/',
staticDirectory: 'static',
esnextModules: ['taro-ui'],//應(yīng)用taroUI的時(shí)候必須設(shè)置******important*******
postcss: {
autoprefixer: {
enable: true,
config: {}
},
cssModules: {
enable: true, // 默認(rèn)為 false,如需使用 css modules 功能,則設(shè)為 true
config: {
namingPattern: 'module', // 轉(zhuǎn)換模式,取值為 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
},
alias: {
'@/pages': path.resolve(__dirname, '..', 'src/pages'),
}
}
module.exports = function (merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
}
return merge({}, config, require('./prod'))
}
5. 復(fù)雜業(yè)務(wù)(預(yù)覽/選擇圖片等)sdk引入
由于微信環(huán)境下的h5需要使用微信提供的weixin-sdk,才能使用微信允許的功能,微信提供的接口如下圖(附網(wǎng)址):
附網(wǎng)站:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
四、常見(jiàn)的問(wèn)題:
1. 子系統(tǒng)具體的頁(yè)面標(biāo)題怎么確定?
跳轉(zhuǎn)過(guò)去默認(rèn)是模塊名稱作為標(biāo)題。如果需要自定義導(dǎo)航欄標(biāo)題,建議使用document.title設(shè)置就行。
2. 涉及到sdk的功能如何進(jìn)行調(diào)試?
真機(jī)調(diào)試。
1.調(diào)式接口,查看接口。點(diǎn)擊小蟲子就可以查看子應(yīng)用得一個(gè)請(qǐng)求情況。
2.真機(jī)調(diào)試查看功能是否適配,采用局域網(wǎng)得方式直接連接本地跑的應(yīng)用。
3. sdk不支持預(yù)覽文件操作?
封裝一個(gè)preiewFile這個(gè)函數(shù)的主要目的是在微信小程序內(nèi)預(yù)覽特定路徑的文件。
這是它如何工作的:
1.首先,函數(shù)接受一個(gè)路徑作為參數(shù),并從該路徑中提取出文件的類型。
2.如果文件類型是圖片(png,jpeg,jpg),那么使用wx.previewImage預(yù)覽該圖片。
3.如果不是圖片,那么函數(shù)會(huì)調(diào)用wx.downloadFile來(lái)下載該文件。在下載過(guò)程中,會(huì)顯示一個(gè)加載提示。下載成功后,如果文件類型是文本文件(txt),那么就使用 wx.getFileSystemManager().readFile 讀取文件內(nèi)容,并通過(guò)模態(tài)對(duì)話框顯示出來(lái)。
4.如果文件類型不是文本文件,那么就嘗試使用 wx.openDocument 打開(kāi)該文件。如果打開(kāi)過(guò)程中出現(xiàn)錯(cuò)誤,錯(cuò)誤詳細(xì)信息將被打印到控制臺(tái)。
整個(gè)函數(shù)的主要功能就是為了提供一個(gè)預(yù)覽文件的方案,包括圖片預(yù)覽,文本內(nèi)容閱讀以及開(kāi)啟文檔。這樣的功能在某些需要預(yù)覽文件內(nèi)容的場(chǎng)景中會(huì)非常有用。
const wx = require('weixin-js-sdk')
function previewFile(path) {
// const path = files[index][this.data.downLoadAttr]
const fileNameArr = name.split('.')
const fileType = fileNameArr[fileNameArr.length-1]
if(fileType == 'png' || fileType == 'jpeg' || fileType == 'jpg'){
wx.previewImage({
current: path, // 當(dāng)前顯示圖片的http鏈接
urls: [path] // 需要預(yù)覽的圖片http鏈接列表
})
return
}
let fs = wx.getFileSystemManager();
wx.showLoading({ title : '文件加載中' });
wx.downloadFile({
url: path,//文件路徑
', //文件路徑
header: {},
success: function (res) {
wx.hideLoading();
var filePath = res.tempFilePath;
if(fileType == 'txt'){
fs.readFile({
filePath:filePath,
encoding:'utf8',
complete(res){
// console.log(res.data);
wx.showModal({
title: '文件內(nèi)容',
content: res.data,
showCancel: false,
confirmText: '確定',
success: (result) => {
if(result.confirm){
}
},
fail: ()=>{},
complete: ()=>{}
});
}
})
}else{
wx.openDocument({
filePath: filePath,
showMenu : true,
// fileType: type, //文件類型
success: function (res) {
},
fail: function (res) {
// wx.showToast({ title: '文件打開(kāi)失敗', icon : 'none' })
console.table(res);
},
complete: function (res) {
}
})
}
},
fail: function (res) {
wx.hideLoading();
console.log('文件下載失敗:',path)
wx.showToast({ title: '文件加載失敗', icon : 'none' })
console.table(res)
},
complete: function (res) {
},
})
}
對(duì)于下載
簡(jiǎn)單粗暴的解決方式是:復(fù)制鏈接讓用戶自行去瀏覽器下載??梢越柚鷆lipboard插件。
4. sdk不支持文件選擇操作?
當(dāng)然,也不能使用taro提供的chooseMessageFile,因?yàn)槲⑿诺膚ebview沒(méi)開(kāi)放給你用。我封裝了原生input的實(shí)現(xiàn)封裝方法chooseFIle,可以直接copy使用。
1.這函數(shù),它用于在Web和非Web環(huán)境(如微信小程序)中選擇文件。它以函數(shù)形式暴露,可以從外部調(diào)用,并傳入一個(gè)對(duì)象參數(shù),這個(gè)參數(shù)包括count(選擇文件的數(shù)量),success(成功的回調(diào)函數(shù)),fail(失敗的回調(diào)函數(shù))和complete(完成的回調(diào)函數(shù))。
2.函數(shù)首先進(jìn)行參數(shù)校驗(yàn),例如檢查傳入的 count 是否為數(shù)字。如果校驗(yàn)失敗,它將調(diào)用失敗回調(diào)函數(shù)并返回一個(gè)Rejected Promise。如果一切正常,我們會(huì)進(jìn)行環(huán)境判斷。
3.如果環(huán)境是Taro的WEB環(huán)境,那么將在頁(yè)面上創(chuàng)建一個(gè)input元素,并設(shè)置它為file類型,以供用戶選擇文件。選擇的文件信息會(huì)被添加到返回的結(jié)果對(duì)象中,然后調(diào)用成功回調(diào)和完成回調(diào)。
4.對(duì)于非Web環(huán)境,它使用Taro的 chooseMessageFile 方法來(lái)選擇文件,這個(gè)函數(shù)通常被用于在微信小程序中選擇聊天文件。
這個(gè)函數(shù)的主要目的是提供一個(gè)通用的文件選擇方案,無(wú)論在Web環(huán)境還是非Web環(huán)境,都可以以相同的方式來(lái)選擇文件。
import Taro from '@tarojs/taro';
//選擇文件
export const chooseFile = function (option) {
const {count = 1, success,url, fail, complete} = option
const res: any = {
errMsg: 'chooseFile:ok',
tempFilePaths: [],
tempFiles: []
}
if (count && typeof count !== 'number') {
res.errMsg = 'error,typeof count is error',
console.error(res.errMsg)
typeof fail === 'function' && fail(res)
typeof complete === 'function' && complete(res)
return Promise.reject(res)
}
if (Taro.getEnv() === Taro.ENV_TYPE.WEB) {
const fileId = "MyUtilsChooseFile"
let taroChooseImageId: any = document.getElementById(fileId)
if (!taroChooseImageId) {
let htmlInputElement: any = document.createElement("input");
htmlInputElement.type = "file"
htmlInputElement.setAttribute('id', fileId)
htmlInputElement.setAttribute('style', 'position: fixed; top: -4000px; left: -3000px; z-index: -300;')
if (count > 1) {
htmlInputElement.setAttribute('multiple', 'multiple')
}
document.body.appendChild(htmlInputElement)
taroChooseImageId = document.getElementById(fileId)
} else {
if (count > 1) {
taroChooseImageId.setAttribute('multiple', 'multiple')
} else {
taroChooseImageId.removeAttribute("multiple")
}
}
taroChooseImageId.onchange = (e) => {
// console.log("onchange",e)
let arr = [...e.target.files]
arr = arr.splice(0, count)
arr && arr.forEach(item => {
let blob = new Blob([item], {
type: e.target.files[0].type
});
let url = URL.createObjectURL(blob);
res.tempFilePaths.push(url)
// res.tempFiles.push({path: url, size: item.size, type: item.type, originalFileObj: item})
console.log("選擇item", item)
res.tempFiles.push({
path: url,
size: item.size,
type: item.type,
name: item.name,
lastModified: item.lastModified,
lastModifiedDate: item.lastModifiedDate,
webkitRelativePath: item.webkitRelativePath
})
})
typeof success === "function" && success(res)
typeof complete === "function" && complete(res)
e.target.value = ''
// document.body.removeChild(taroChooseImageId)
}
//觸發(fā)選擇
taroChooseImageId.click()
} else {
Taro.chooseMessageFile({
count: count,
type: 'file',
success: function (res) {
// console.log("選擇文件",res)
success ? success(res) : ""
}
})
}
}
使用
chooseFile({
count:2,
success(res){
console.log(res)
}
})
5. sdk不支持文件上傳操作?
用Taro自帶的Taro.uploadFile(option)實(shí)現(xiàn),示例如下:
chooseFile({
count:2,
success(res){
console.log(res)
Taro.uploadFile({
url:url
filePath:res.tempFiles[0].path,
name:res.tempFiles[0].name,
formData: {},
success (res){
const data = res.data
//do something
}
})
}
})
6. sdk不支持小程序跳轉(zhuǎn)?如何實(shí)現(xiàn)
先進(jìn)行環(huán)境的判斷
// 判斷當(dāng)前環(huán)境是否為小程序
const ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
wx.miniProgram.getEnv((res) => {
if (res.miniprogram) {
console.log('在小程序內(nèi)');
} else {
console.log('不在小程序內(nèi)');
}
});
} else {
console.log('不在微信瀏覽器內(nèi)');
}
// 小程序跳轉(zhuǎn)方法
wx.miniProgram.navigateTo({
url:'/pages/index/index', // 指定跳轉(zhuǎn)至小程序頁(yè)面的路徑
success: (res) => {
console.log(res); // 頁(yè)面跳轉(zhuǎn)成功的回調(diào)函數(shù)
},
fail: (err) => {
console.log(err); // 頁(yè)面跳轉(zhuǎn)失敗的回調(diào)函數(shù)
}
});
// 通過(guò)鏈接與小程序通訊傳參
// 靜態(tài)參數(shù)傳輸
wx.miniProgram.navigateTo({
url:'/pages/index/index?id=1', // id:所需參數(shù)
success: (res) => {
console.log(res); // 頁(yè)面跳轉(zhuǎn)成功的回調(diào)函數(shù)
},
fail: (err) => {
console.log(err); // 頁(yè)面跳轉(zhuǎn)失敗的回調(diào)函數(shù)
}
});
// 動(dòng)態(tài)參數(shù)傳輸
let id = 1;
wx.miniProgram.navigateTo({
url:'/pages/index/index?id=' + id, // id:所需參數(shù)(動(dòng)態(tài)參數(shù)需放在引號(hào)外小程序才可識(shí)別)
success: (res) => {
console.log(res); // 頁(yè)面跳轉(zhuǎn)成功的回調(diào)函數(shù)
},
fail: (err) => {
console.log(err); // 頁(yè)面跳轉(zhuǎn)失敗的回調(diào)函數(shù)
}
});
如果不再小程序內(nèi)跳轉(zhuǎn)會(huì)報(bào)錯(cuò)。
解決思想:
首先,webview內(nèi)嵌h5,從h5頁(yè)面是不可以直接使用wx.miniProgram.navigateTo 方法跳轉(zhuǎn)到其他小程序,所以具體思路應(yīng)該是小程序A => webview內(nèi)嵌 h5 => 從h5調(diào)回到小程序A的中轉(zhuǎn)頁(yè)面 => 在小程序A中 使用wx.navigateToMiniProgram 方法跳轉(zhuǎn)到 小程序B
1.我們采用自定義的navigateToMiniProgramForWebview函數(shù)來(lái)觸發(fā)從當(dāng)前小程序跳轉(zhuǎn)到另一個(gè)小程序。這個(gè)函數(shù)接收兩個(gè)參數(shù),wx對(duì)象和包含跳轉(zhuǎn)信息的params對(duì)象。
2.wx對(duì)象是由微信API提供的一個(gè)核心對(duì)象,帶有微信小程序的接口。params對(duì)象包含了必須的跳轉(zhuǎn)信息,比如目標(biāo)小程序的appId,路徑(path),額外的數(shù)據(jù)(extraData),以及小程序的版本.
3.函數(shù)體中的第一步是創(chuàng)建一個(gè)新的對(duì)象 passParams,它復(fù)制了params的所有屬性,然后把extraData屬性轉(zhuǎn)換成 JSON 字符串,并且添加了一個(gè)新的屬性:type,在這個(gè)例子中其值為:‘navigateToMiniProgram’。
4.接下來(lái),將這個(gè)passParams對(duì)象通過(guò)一個(gè)叫formatParams的函數(shù)轉(zhuǎn)換成一個(gè)URL查詢字符串,和路徑組合成一個(gè)完整的URL。在這個(gè)例子中,這個(gè)URL指向小程序的一個(gè)特定頁(yè)面:webviewMiddlePage,并帶有跳轉(zhuǎn)信息作為查詢參數(shù)。
5.最后一步是通過(guò) wx.miniProgram.navigateTo 接口, 使用這個(gè)URL進(jìn)行導(dǎo)航。這將觸發(fā)在當(dāng)前小程序中打開(kāi)webviewMiddlePage 頁(yè)面,然后這個(gè)頁(yè)面會(huì)解析URL中的參數(shù),并根據(jù)跳轉(zhuǎn)信息完成從當(dāng)前小程序到目標(biāo)小程序的跳轉(zhuǎn)。
注意,這個(gè)函數(shù)中使用了兩次跳轉(zhuǎn)。
第一次是在當(dāng)前小程序內(nèi)部,跳轉(zhuǎn)到 webviewMiddlePage頁(yè)面。
第二次跳轉(zhuǎn)是在 webviewMiddlePage 頁(yè)面中,完成從當(dāng)前小程序到目標(biāo)小程序的跳轉(zhuǎn)。通過(guò)這種方式設(shè)計(jì),使得跳轉(zhuǎn)過(guò)程可以攜帶更復(fù)雜的數(shù)據(jù),同時(shí)繞過(guò)微信小程序navigateToMiniProgram 方法對(duì)傳遞數(shù)據(jù)量的限制。
const navigateToMiniProgramForWebview =(wx, params:any = {})=> {
const passParams = {
...params,
extraData:JSON.stringify(params.extraData || {}),
type: 'navigateToMiniProgram'
}
const url = `/pages/webviewMiddlePage/index?${formatParams(passParams)}`//跳回我們小程序自定義得頁(yè)面請(qǐng)求打開(kāi)另外一個(gè)小程序
wx?.miniProgram?.navigateTo({url})
}
navigateToMiniProgramForWebview(wx, {
appId: '',//必傳 跳轉(zhuǎn)小程序唯一標(biāo)識(shí)
path: ``,//必傳 跳轉(zhuǎn)后初始頁(yè)面路徑
//develop(開(kāi)發(fā)版),trial(體驗(yàn)版),release(正式版 )
envVersion: 'release',//必傳 跳轉(zhuǎn)小程序的版本
})
function formatParams(obj: any){
let arr: string[] = []
Object.keys(obj).forEach(key => {
if(obj[key] && typeof obj[key] === 'string') {
arr.push(`${key}=${encodeURIComponent(obj[key])}`)
}
})
return arr.join('&')
}
如果是app或者h(yuǎn)5直接window.open
7.IOS日期顯示Invalid date
注意:iso 這樣 new Date(‘2021-02-11’) 返回的就是Invaild Date。
new Date(‘2021/02/11’) '/'才是正常的
五、讓人哭笑不得得代碼
1.發(fā)起了六次請(qǐng)求。我挺搞不懂他是怎么寫得。然后我就重構(gòu)了頁(yè)面。
2.人生無(wú)語(yǔ),查看訂單后,不能保存id嘛,又進(jìn)行一次查詢。然后在刪除。然后我又要重構(gòu)頭就是怎么禿得
是不是很有意思
六、對(duì)于多端開(kāi)發(fā)
小程序得每年認(rèn)證,對(duì)于企業(yè)來(lái)說(shuō)將會(huì)采用更多得h5頁(yè)面去嵌入一個(gè)總的小程序平臺(tái),而不是采用單獨(dú)得開(kāi)發(fā)發(fā)布,因?yàn)槿绻J(rèn)證幾個(gè)小程序或者十幾個(gè)小程序,企業(yè)覺(jué)得這樣得費(fèi)用不是很值得,更青睞于h5一套嵌入,webapp也是如此,釘釘也是如此,其它得也是。、taro也可以適配鴻蒙系統(tǒng)得開(kāi)發(fā)。uniapp 是一種基于 Vue.js 的跨平臺(tái)開(kāi)發(fā)框架。而Taro 是一種基于 React 的多端開(kāi)發(fā)框架。taro跟uniapp,taro跟react框架搭配,uniapp跟Vue搭配。兩個(gè)框架我都學(xué)習(xí)使用。感受就是語(yǔ)法不一樣,解決思路還是一樣得。做多了項(xiàng)目后,會(huì)發(fā)現(xiàn),其實(shí)框架只是實(shí)現(xiàn)需求得一種工具,更重要得是解決問(wèn)題得思想跟經(jīng)驗(yàn)。就像我搭檔一樣,他工作三年多了,他說(shuō)他之前是使用vue開(kāi)發(fā)得,對(duì)小程序,跟webapp也不是很熟。雖然我之前做過(guò),但是跟他一起工作給我得一種感覺(jué)是他上手快。解決思路很清晰,只是語(yǔ)法切換而已,能搞快速得定位問(wèn)題,并參考學(xué)習(xí)。
uniapp搭建學(xué)習(xí)
項(xiàng)目基于 uniapp + Vue3 + vite + pinia + ts + axios 項(xiàng)目模板快速開(kāi)發(fā),適用于小程序開(kāi)發(fā) h5。
項(xiàng)目使用了 vite 作為開(kāi)發(fā)工具,支持 esm、cjs、iife 三種打包方式,支持按需加載,支持熱更新。
github:https://github.com/wskang12138/aniapp-learn
聲明:這個(gè)框架不是我搭建得,我也只是demo下來(lái)學(xué)習(xí),改改就成我得了,哈哈哈哈哈哈。
七、總結(jié)
對(duì)于多端得適配,四種情況:頂部導(dǎo)航欄得適配,頁(yè)面樣式得適配,功能得適配,其它。
對(duì)于頂部導(dǎo)航欄得適配,這個(gè)簡(jiǎn)單,判斷環(huán)境做好封裝顯示就好了。頁(yè)面樣式得適配,媒體查詢?yōu)榛鶞?zhǔn),flex為區(qū)間布局。功能得適配:得翻閱文檔學(xué)習(xí)了。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-814498.html
參考:https://github.com/uileader/touchwx文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-814498.html
到了這里,關(guān)于H5嵌入小程序適配方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!