HBuilder X打包运行鸿蒙应用(vue2 -> vue3)
1. manifest.json配置为vueVersion: 32. main.js调解(下方已增补)
3. store调解
import { createStore } from 'vuex'
const state = {}
const getters = {}
const mutations = {}
const actions = {}
// 创建 Vuex Store
const store = createStore({
state,
getters,
mutations,
actions,
});
export default store
4. 增加入口文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = "CSS" in window && typeof CSS.supports === "function" && (CSS.supports("top: env(a)") || CSS.supports("top: constant(a)"));
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ", viewport-fit=cover" : "") +
'" />'
);
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
5. require方式调解为import导入方式
6. main导入uni.promisify.adaptor3-2.js uniapp Vue 3转Vue 2 API Promise 化调用效果的方式
API Promise 化 调用效果的方式
// uni.promisify.adaptor3-2.js
uni.addInterceptor({
returnValue(res) {
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
return res;
}
const returnValue = ;
return res
.then((res) => {
returnValue = res;
})
.catch((err) => {
returnValue = err;
})
.then(() => returnValue);
},
});
7. 项目运行,组件调解,样式调解,vue2组件升级为vue3组件;vue3不建议利用标签样式,比如p, img
8. jweixin-module等部分利用动态导入方式
// loadJweixin.js
xport async function loadJweixin() {
try {
// 动态导入 jweixin-module
return await import('jweixin-module');
} catch (error) {
console.error('Failed to load jweixin-module:', error);
throw error;
}
}
// main.js
import App from "./App";
// 全局状态管理
import store from "./store";
// #ifdef VUE3
import { createSSRApp } from "vue";
import "./uni.promisify.adaptor3-2";
import uViewPlus from "@/uni_modules/uview-plus";
// #ifdef H5
import { loadJweixin } from "./utils/loadJweixin.js";
// #endif
// 不能修改导出的 createApp 方法名,不能修改从 Vue 中导入的 createSSRApp。
export function createApp() {
// 创建应用实例
const app = createSSRApp(App);
// 使用 uViewPlus
app.use(uViewPlus);
// 设置全局配置
app.config.globalProperties.$store = store;
// #ifdef H5
loadJweixin().then((res) => {
app.config.globalProperties.$jweixin = res;
});
// #endif
// 忽略某些元素
// app.config.ignoredElements.push('wx-open-launch-weapp');
return {
app,
};
}
// #endif
9. H5各个界面运行,出现异常进行代码调解
10. 适配小程序
11. 适配APP
12. 适配鸿蒙模仿器,以及处置惩罚tabbar界面不显示问题
[*]a). 白屏不展示问题按照官网方式,注释pages.json,二分法测试各个界面
[*]b). tabbar界面第一次不显示数据:第一次打开onShow不会实行,实行函数需要在onLoad内里
[*]c). axios拦截器不支持,接口会没有相应
13. 华为安卓权限监听显示顶部蒙层,导入permissionListener.js文件,利用的uni.createRequestPermissionListener
[*]a). 华为权限索取行为
/**
* @Author:liyuqi
* @Date:2024-09-06 10:38:45
* @LastEditors:liyuqi
* @Description:uni.createRequestPermissionListener()
* @Description:安卓权限说明顶部蒙层
* @Description:文档地址:https://uniapp.dcloud.net.cn/api/system/create-request-permission-listener.html
* @Description:注意:HBuilderX (4.0+) android 平台支持;HBuilderX 4.01 Vue2项目需要使用自定义基座测试监听权限申请的功能,标准基座暂不支持测试。
*/
// #ifndef APP
export default null;
// #endif
// #ifdef APP
let permissionListener = null;
// 是安卓平台,同时有uni.createRequestPermissionListener这个api
if (getApp().globalData.isAndroid && uni.createRequestPermissionListener) {
permissionListener = uni.createRequestPermissionListener();
}
let canRunListener = true;// 是否可以执行所有监听方法
let canStopListener = true; // 是否可以执行取消所有监听方法,避免唤起权限会触发App.vue的onHide生命周期
const permissionEnums = {
"ACCESS_COARSE_LOCATION": {
name: "定位",
explain: "展示附近店铺、填写收货地址等相关功能"
},
"ACCESS_FINE_LOCATION": {
name: "定位",
explain: "展示附近店铺、填写收货地址等相关功能"
},
"READ_EXTERNAL_STORAGE": {
name: "存储",
explain: "上传图片、上传视频等相关功能"
},
"CAMERA": {
name: "相机",
explain: "扫二维码、拍摄图片等相关功能"
},
"WRITE_EXTERNAL_STORAGE": {
name: "存储",
explain: "把图片保存到相册等相关功能"
}
}
/**
* 权限说明文字
* @param {String} permissionName例如:ACCESS_COARSE_LOCATION
*/
const texts = (permissionName) => {
let title = "";
let content = "";
let permissionInfo = permissionEnums || null;
if (permissionInfo) {
const { name, explain } = permissionInfo;
title = `${name}权限使用说明`;
content = `将获取${name}权限,用于${explain}`;
} else {
title = "";
content = "";
}
return {
title,
content
}
};
/**
* 绘画顶部权限说明
* 文档地址:https://www.html5plus.org/doc/zh_cn/nativeobj.html
* @function drawView title标题,content描述使用说明
* @function hideView 隐藏顶部权限说明
*/
let view = null;
const drawView = ({ title, content }) => {
console.log("drawView方法的参数值:", title, content);
if (view || !title || !content) return; // 没有标题和内容则return出去
const { windowTop, windowWidth, statusBarHeight } = uni.getSystemInfoSync();
const topHeight = windowTop + statusBarHeight;
const distance = {
box: 10, // 盒子距离视图两边的距离
text: 20 // 文字距离视图两边的距离
}
// 标题的相关样式
const titleStyle = {
size: 16,
height: 16,
top: `${topHeight + 22}`,
color: "#000",
}
// 内容的相关样式
const contentStyle = {
size: 14,
height: 0,
top: `${parseInt(titleStyle.top) + titleStyle.height + 6}`,
color: "#656563",
}
const contentLength = content.length; // 权限说明内容文字长度
const contentWidth = windowWidth - distance.text * 2; // 内容的宽度
const contentRowCount = Math.floor(contentWidth / contentStyle.size); // 一行占几个文字
const contentRows = Math.ceil(contentLength / contentRowCount); // 当前内容占几行
contentStyle.height = contentRows * (contentStyle.size + 4); // 内容的高度
/**
* @description 计算盒子的高度
* 获取content到盒子顶部距离:parseInt(contentStyle.top) - topHeight - distance.box
* content的高度:contentStyle.height
* 获取content到盒子底部的距离:(distance.text - distance.box)
*/
const boxHeight = (parseInt(contentStyle.top) - topHeight - distance.box) + contentStyle.height + (distance.text - distance.box);
view = new plus.nativeObj.View('per-modal', {
top: '0',
left: '0',
width: '100%',
backgroundColor: 'rgba(0,0,0,0.2)'
})
view.drawRect({
color: '#fff',
radius: '5px',
}, {
top: `${topHeight + distance.box}px`,
left: `${distance.box}px`,
right: `${distance.box}px`,
height: `${boxHeight}px`
})
view.drawText(title, {
top: `${titleStyle.top}px`,
left: `${distance.text}px`,
height: `${titleStyle.height}px`
}, {
size: `${titleStyle.size}px`,
align: "left",
color: titleStyle.color,
weight: "bold"
})
view.drawText(content, {
top: `${contentStyle.top}px`,
left: `${distance.text}px`,
right: `${distance.text}px`,
height: `${contentStyle.height}px`,
}, {
size: `${contentStyle.size}px`,
lineSpacing: "2px",
align: "left",
color: contentStyle.color,
verticalAlign: "top",
whiteSpace: "normal"
})
let timer = setTimeout(() => {
view && view.show();
clearTimeout(timer);
timer = null;
}, 200)
}
// 关闭顶部权限说明
const hideView = () => {
if (view) {
view.hide();
view = null;
}
}
// 监听权限方法
const listenerFunc = () => {
stopFunc(); // 取消所有监听方法
if (canRunListener && permissionListener) {
let permissionName = ""; // 权限名称
let hasConfirm = false; // 是否有权限弹窗(触发permissionListener.onConfirm这个回调)
canRunListener = false;
canStopListener = false;
// 监听申请系统权限
permissionListener.onRequest((e) => {
console.log("permissionListener.onRequest回调:", e);
if (Array.isArray(e) && e.length > 0) {
const stringToArray = e.split(".");
permissionName = stringToArray;
console.log("权限名称:", permissionName);
}
});
// 监听弹出系统权限授权框
permissionListener.onConfirm((e) => {
console.log("permissionListener.onConfirm回调:", e);
hasConfirm = true;
if (permissionName) {
drawView(texts(permissionName));
}
});
// 监听权限申请完成
permissionListener.onComplete((e) => {
console.log("permissionListener.onComplete回调:", e);
// e.length === 0:权限列表无值,则不继续做相对逻辑
if (e.length === 0) return;
let name = ""; // 权限名称
let explain = ""; // 权限说明
if (permissionName && permissionEnums) {
name = permissionEnums.name;
explain = permissionEnums.explain;
}
const Manifest = plus.android.importClass("android.Manifest");
const MainActivity = plus.android.runtimeMainActivity();
const permissionStatus = MainActivity.checkSelfPermission(Manifest.permission);
console.log("当前权限状态:", permissionStatus);
/**
* @description 永久拒绝该权限,则引导用户前往设置页
* permissionStatus != 0:权限状态是拒绝
* !hasConfirm:没有permissionListener.onConfirm这个回调
*/
if (permissionStatus != 0 && !hasConfirm && name && explain) {
uni.showModal({
title: "温馨提示",
content: `开启${name}权限后,才能${explain}`,
showCancel: true,
confirmText: "去设置",
success: (res) => {
if (res.confirm) {
uni.openAppAuthorizeSetting();
}
}
})
return;
}
canStopListener = true;
hideView();
});
}
}
// 取消所有监听方法
const stopFunc = () => {
if (canStopListener && permissionListener) {
console.log("执行permissionListener.stop()方法");
canRunListener = true;
hideView();
permissionListener.stop();
}
}
let exportObj = null;
if (permissionListener) {
exportObj = {
listenerFunc,
stopFunc
};
} else {
exportObj = null;
}
export default exportObj;
// #endif
导入方式
// App.vue
// #ifdef APP
import permissionListener from"./utils/permissionListener.js";
// #endif
export default {
onLaunch: function(options) {
},
onShow() {
// #ifdef APP
permissionListener && permissionListener.listenerFunc();
// #endif
},
onHide() {
// #ifdef APP
permissionListener && permissionListener.stopFunc();
// #endif
},
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]