專案背景:
公司為了實作小程式與H5頁面共同覆寫,全面推廣,特此想將已有的小程式進行快速改造上線(二周內),研發出H5版本,目前公司前端技術較為薄弱,現有的技術解決方案還停留在JSP,
問題:
如何將目前已經上線運行的原生小程式(40多個頁面)快速轉化為原生H5頁面,實作快速上線,是采用我們較為熟悉的JSP還是參考目前最熱門的前后端分離VUE框架呢???
想法:
1)采用熟練的JSP框架,每人一天可以改造2個頁面左右,計劃投入2人,風險最小;
2)采用主流分布式Vue框架,時間未知,風險未知;
首先自我介紹下,本人是一名JAVA開發工程師,平時喜歡研究相關主流技術和挑戰自己,對此我還是比較傾向于第二種解決方案,但是第二種解決方案無疑是最復雜,最耗時,最未知,風險最大,公司內沒有人愿意承接,于是我抱著學習和研究的態度以及對主流技術的向往,我找到我們領導我是這樣說的:我還是比較建議公司采用第二種方案,1)這無疑是給我們進行敲門磚及學習的機會;2)這是公司提升前端技術能力與主流技術看齊的機會,最后公司同意了我建議,采用方案二,有我來承接此事,進行牽頭負責,
中間心酸程序忽略,剛接下來第一天就后悔了,VUE用都沒用過,還怎么玩,于是我花了大量的時間,看了大量文獻,我這里使用到是Vue 2 + Vant 2 + axios + router,
(1)VUE官方技術檔案:
https://v2.cn.vuejs.org/v2/guide/
https://cli.vuejs.org/zh/guide/creating-a-project.html
(2)參考了Vant 2組件:
https://youzan.github.io/vant/v2/#/zh-CN/toast
(3)同時也參考很多成熟開源VUE框架:
若依(也是從這個專案中進行借鑒與參考):http://doc.ruoyi.vip/ruoyi/
于是我花費了3天時間終于完成了VUE專案框架搭建及第一個小程式頁面轉H5頁面,心想如果是這樣的進度,指定時間完成是不可能的了,有沒有什么方法可以快速將小程式組件替換成VUE呢,報著這個想法就開干,也是網上找了很多案例都不是很齊全,沒辦法我只能自己進行撰寫工具方法,廢話不多說之前上干貨,
首先要想撰寫工具方法必須要知道小程式和VUE有哪些特性,以及哪些是等價效果,這里我進行了簡單梳理:
頁面事件替換:
view 替換 div
image替換img
bindinput=替換v-on:input=
bindtap=替換@click=
<rich-text nodes="{{detail.prizeDetailContent}}"></rich-text>替換<div v-html="detail.prizeDetailContent"></div>
Js替換:
e.detail.value替換e.target.value
app.globalData.替換this.$globalData.(globalData這里是需要在main.js定義替換的全域變數)
wx.showLoading({title: "加載中",mask: true,});
替代寫法
this.$toast.loading({ message: '加載中...',forbidClick: true, duration: 0,});(這里是參考了Vant 2)
wx.getStorageSync替代寫法localStorage.getItem
wx.setStorageSync替代寫法localStorage.setItem
wx.navigateTo替換window.location.href="https://www.cnblogs.com/cbw-mango/archive/2022/09/05/"
wx.redirectTo替換window.open();
wx.hideLoading();替換this.$toast.clear();(這里是參考了Vant 2)
樣式替換:
//100rpx -> 5rem rpx替換rem(考慮到移動端兼容引入rem計量單位) 等等,我這里不一一列舉了,其次介紹下實作步驟及原理: VUE各個檔案目錄含義說明:
具體步驟如下:
(1)VUE采用的是單頁面設計思路,所有js,html,css都在一個頁面內完成,對此我們需要先將小程式指定檔案夾下面的內容進行粘貼過來,

(2)進入“replace”目錄,將復制完成后的代碼,粘貼到“replace.vue” 點擊“replaceUtil.js” 右鍵,在集成終端中打開,運行代碼“node .\replaceUtil.js”

以上兩步完成絕大部分的小程式轉VUE特性功能點,個別較為復雜的可能需要人工進行修改調整,(列入wx.request這些目前我們的寫法是人工進行修改改為axios,當然也可以進行二次封裝,減少代碼改動地方,歡迎大家進行嘗試,我這里這里主要是為了去wx化防止誤導,選擇了人工進行修改調整)
具體后臺請求介面方面我們采用的axios具體寫法如下:
1、 使用axios組件完成后臺請求,第一步“service”目錄下新建“.js”

2、 參考js,

3、呼叫方式

以上就是我對VUE轉H5相關理解和具體實作思路,歡迎大家進行評論和指導!!!
相關原始碼如下:
(1)核心替換代碼replaceUtil.js
const fs = require("fs");
let fileName = "replace.vue"; // 需要替換字符的檔案名
fs.readFile(`${__dirname}/${fileName}`, "utf8", (err, data) => {
console.log(__dirname);
console.log(fileName);
if (err) {
console.log("readFile error");
console.log(err);
}
console.log("readFile sussce");
// 替換字符
let rs = changeWxToVue(data, ["label", "rpx", "if", "for", "tap", "labjs"]);
// console.log(rs)
fs.writeFile(`${__dirname}/${fileName}`, rs, "utf8", (err) => {
if (err) {
console.log("writeFile error");
}
});
});
/**
*
* @param {*} data vue檔案字符
* @param {*} changeArr 陣列格式,需要替換的字符,以陣列格式傳遞;
* ['label']:只替換view、text、block標簽
* ['label','rpx']:替換view、text、block標簽 和 rpx,rpx的數值需要是基準為750px的標準設計稿,100rpx->50px
* ['for']:for標簽替換不包括key,否則正則運算式太長了
* @returns
*/
function changeWxToVue(data, changeArr) {
for (let i = 0; i < changeArr.length; i++) {
if (changeArr[i] == "label") {
// 替換view -> div, text -> span
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/<(/(view)|view.*)>/g, (a) => {
return a.replace(/view/g, "div");
});
data = data.replace(/<(\/(text)|text.*)>/g, (a) => {
return a.replace(/text/g, "span");
});
data = data.replace(/<(\/(block)|block.*)>/g, (a) => {
return a.replace(/template/g, "span");
});
}
if (changeArr[i] == "rpx") {
// 替換100rpx -> 5rem
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/(/d*)rpx/g, (num) => {
return (parseInt(num) / 20).toFixed(2).toString() + "rem";
});
}
if (changeArr[i] == "if") {
// 替換wx:if -> v-if
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/(wx:if|wx:elif|wx:else)="{{(((?![-=]).)*)}}"/g,
(a, b, c) => {
console.log(a,b,c);
c = c.replace(/(^\s*)|(\s*$)/g, "");
let vue = "";
switch (b) {
case "wx:if":
vue = "v-if";
break;
case "wx:elif":
vue = "v-else-if";
break;
case "wx:else":
vue = "v-else";
break;
}
return `${vue}="${c}"`;
}
);
}
if (changeArr[i] == "for") {
// 替換wx:for="{{list}}" wx:for-item="item1" wx:for-index="index1" -> v-for=""
let forRegArr = [
/\swx:for="{{(((?![-=]).)*)}}"([^key].*)wx:for-item="(((?!-).)*)"([^key].*)wx:for-index="(((?![-=]).)*)"/g,
/\swx:for="{{(((?![-=]).)*)}}"([^key].*)wx:for-index="(((?!-).)*)"([^key].*)wx:for-item="(((?![-=]).)*)"/g,
/\swx:for="{{(((?![-=]).)*)}}"/g,
];
data = data.replace(forRegArr[0], (a, b, c, d, e, f, g, h, i, j, k) => {
// console.log('a-',a,'\nb-',b,'\nc-',c,'\nd-',d,'\ne-',e,'\nf-',f,'\ng-',g,'\nh-',h,'\ni-',i,'\nj-',j,'\nk-',k);
if (e) {
if (h) {
return ` v-for="(${e}, ${h}) in ${b}" `;
} else {
return ` v-for="${e} in ${b}" `;
}
}
});
data = data.replace(forRegArr[1], (a, b, c, d, e, f, g, h, i, j, k) => {
// console.log('a-',a,'\nb-',b,'\nc-',c,'\nd-',d,'\ne-',e,'\nf-',f,'\ng-',g,'\nh-',h,'\ni-',i,'\nj-',j,'\nk-',k);
if (h) {
if (e) {
return ` v-for="(${h}, ${e}) in ${b}" `;
} else {
return ` v-for="${h} in ${b}" `;
}
}
});
data = data.replace(forRegArr[2], (a, b) => {
return ` v-for="item in ${b}" `;
});
}
if (changeArr[i] == "tap") {
// bindtap || catchtap -> @click
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/(bindtap|bind:tap|catchtap)="(((?!-).)*)"/g,
(a, b, c) => {
return `@click="${c}"`;
}
);
// bindinput -> v-on:input=
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/(bindinput)="(((?!-).)*)"/g, (a, b, c) => {
return `v-on:input="${c}"`;
});
}
if (changeArr[i] == "data") {
// data-index="{{index}}" -> data-index="index"
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/data-(((?!-).)*)="{{(((?!-).)*)}}"/g,
(a, b, c, d) => {
return `data-${b}="${d}"`;
}
);
}
if (changeArr[i] == "labjs") {
// e.detail.value -> e.target.value
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/e.detail.value/g,"e.target.value");
// app.globalData. -> this.$globalData.
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/app.globalData./g,"this.$globalData.");
// wx.getStorageSync -> localStorage.getItem
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/wx.getStorageSync/g,"localStorage.getItem");
// wx.setStorageSync -> localStorage.setItem
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/wx.setStorageSync/g,"localStorage.setItem");
// wx.hideLoading -> localStorage.setItem
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/wx.setStorageSync/g,"localStorage.setItem");
// wx.hideLoading -> this.$toast.clear
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/wx.hideLoading/g,"this.$toast.clear");
data = data.replace(/wx:key=\"\*this\"/g, "");
data = data.replace(
/wx:for=["|']\s*\{\{([^\}]+)\}\}\s*["|']/g,
($0, $1) => 'v-for="(item, index) in ' + $1 + '"'
);
data = data.replace(
/wx:for-items=["|']\s*\{\{([^\}]+)\}\}\s*["|']/g,
($0, $1) => 'v-for="(item, index) in ' + $1 + '"'
);
data = data.replace(
/wx:key=["|']([^"|']+)["|']/g,
($0, $1) => ':key="' + $1 + '"'
);
// if
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/wx:if=["|']\s*\{\{([^\}]+)\}\}\s*["|']/g,
($0, $1) => 'v-if="' + $1 + '"'
);
// elif
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/wx:elif=["|']\s*\{\{([^\}]+)\}\}\s*["|']/g,
($0, $1) => 'v-else-if="' + $1 + '"'
);
// else
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/wx:else/g,"v-else");
data = data.replace(/<view/g, "<div");
data = data.replace(/\/view>/g, "/div>");
data = data.replace(/<text/g, "<span");
data = data.replace(/\/text>/g, "/text>");
data = data.replace(/<image([^>]+)/g, ($0, $1) => "<img " + $1 + "/");
data = data.replace(/<input([^>]+)/g, ($0, $1) => "<input " + $1 + "/");
data = data.replace(/<\/image>/g, "");
data = data.replace(/<\/input>/g, "");
data = data.replace(
/<icon([^>]+)/g,
($0, $1) => '<i style="display:inline-block" ' + $1 + "/>"
);
data = data.replace(
/bind([^=|\s]+)=["|']([^"|'|\s]+)["|']/g,
($0, $1, $2) => "@" + $1 + '="' + $2 + '"'
);
data = data.replace(/navigator/g, "router-link");
data = data.replace(/\"\/images/g, '"../../assets');
data = data.replace(/this.data./g, "this.");
data = data.replace(/that.data./g, "this.");
data = data.replace(/..\/..\/utils\/wxml\/common.wxml/g, "../../utils/vue/common.vue");
data = data.replace(/..\/..\/utils\/wxss\/common.wxss/g, "../../utils/css/common.css");
// 變數
// data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/data-([^=|/s]+)=["|']\{\{([^\}]+)\}\}["|']/g, ($0,$1,$2)=> ':data-'+$1+'="'+$2+'"')
data =https://www.cnblogs.com/cbw-mango/archive/2022/09/05/ data.replace(
/([^\s|=]+)=["|']\{\{([^\}]+)\}\}["|']/g,
($0, $1, $2) => ":" + $1 + '="' + $2 + '"'
);
// 變數輪播圖替換
data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/data.replace(/);
data = data.replace(/\/swiper-item>/g, "/van-swipe-item>");
data = data.replace(/<swiper/g, "<van-swipe");
data = data.replace(/\/swiper>/g, "/van-swipe>");
data = data.replace(/:autoplay=\"autoplay\"/g, ":autoplay=\"interval\"");
}
}
return data;
}
(2)axios.js:
/** * 嚴肅宣告: * 開源版本請務必保留此注釋頭資訊,若洗掉我方將保留所有法律責任追究! * 本系統已申請軟體著作權,受國家著作權局知識產權以及國家計算機軟體著作權保護! * 可正常分享和學習原始碼,不得用于違法犯罪活動,違者必究! * Copyright (c) 2020 陳尼克 all rights reserved. * 著作權所有,侵權必究! */ import axios from "axios"; import { Toast } from "vant"; import router from "../router"; import globalData from "../utils/global.js"; import qs from 'qs'; axios.defaults.baseURL = ''; axios.defaults.timeout = 30000; axios.defaults.withCredentials = true; axios.defaults.headers["X-Requested-With"] = "XMLHttpRequest"; axios.defaults.headers["token"] = localStorage.getItem("token") || ""; axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"; // 請求攔截器 axios.interceptors.request.use( (config) => { // config 請求的所有資訊 // console.log(config); // 設定請求頭 if (config.method === "post" && !!config.data && config.data !== "") { config.headers = { Accept: "*/*", "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", }; if(config.url === '/pages/sri/order/uploadImg'){ config.headers["Content-Type"] = "multipart/form-data" } else { config.data = qs.stringify(config.data, {arrayFormat:'comma'}) } } // if (config.method === "put" && !!config.params && config.params !== "") { // config.headers = { // Accept: "*/*", // "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", // }; // } // if (config.method === "delete") { // if (!!config.params && !!config.params.data) { // config.headers = { // Accept: "*/*", // "Content-Type": "application/json;charset=UTF-8", // }; // config.data = https://www.cnblogs.com/cbw-mango/archive/2022/09/05/config.params; // config.params = ""; // } // } return config; // 將配置完成的config物件回傳出去 如果不回傳 請求講不會進行 }, (err) => { // 請求發生錯誤時的相關處理 拋出錯誤 console.log("服務端請求例外!"); return Promise.reject(err); } ); // 回應攔截器 axios.interceptors.response.use( (res) => { return res; }, (err) => { console.log("服務端回應例外!"); return Promise.reject(err); } ); export default axios;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/504480.html
標籤:其他
上一篇:前端js vue的語音播報
