uni-app 最新版本4.45在打包微信小程序时uni.getSystemInfoSync并非同步获取设备信息
uni-app 最新版本4.45在打包微信小程序时uni.getSystemInfoSync并非同步获取设备信息
产品分类
uniapp/小程序/微信
开发环境信息
项目 | 信息 |
---|---|
PC开发环境操作系统 | Windows |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 4.45 |
第三方开发者工具版本号 | 1.06.2407120 |
基础库版本号 | 3.14 |
项目创建方式 | HBuilderX |
示例代码
import { ref, reactive, toRefs } from "vue";
import { useStore } from "vuex";
import _isFunction from "lodash/isFunction";
function getSystemInfo() {
if (uni.globalSystemInfo && !uni.globalSystemInfo.ios) {
return uni.globalSystemInfo;
} else {
// h5环境下忽略navbar
if (!_isFunction(uni.getSystemInfoSync)) {
return null;
}
let systemInfo = uni.getSystemInfoSync() || {
model: "",
system: "",
};
let ios = !!(systemInfo.system.toLowerCase().search("ios") + 1);
let rect;
try {
rect = uni.getMenuButtonBoundingClientRect
? uni.getMenuButtonBoundingClientRect()
: null;
if (rect === null) {
throw "getMenuButtonBoundingClientRect error";
}
//取值为0的情况 有可能width不为0 top为0的情况
if (!rect.width || !rect.top || !rect.left || !rect.height) {
throw "getMenuButtonBoundingClientRect error";
}
} catch (error) {
let gap = ""; //胶囊按钮上下间距 使导航内容居中
let width = 96; //胶囊的宽度
if (systemInfo.platform === "android") {
gap = 8;
width = 96;
} else if (systemInfo.platform === "devtools") {
if (ios) {
gap = 5.5; //开发工具中ios手机
} else {
gap = 7.5; //开发工具中android和其他手机
}
} else {
gap = 4;
width = 88;
}
if (!systemInfo.statusBarHeight) {
//开启wifi的情况下修复statusBarHeight值获取不到
systemInfo.statusBarHeight =
systemInfo.screenHeight - systemInfo.windowHeight - 20;
}
rect = {
//获取不到胶囊信息就自定义重置一个
bottom: systemInfo.statusBarHeight + gap + 32,
height: 32,
left: systemInfo.windowWidth - width - 10,
right: systemInfo.windowWidth - 10,
top: systemInfo.statusBarHeight + gap,
width: width,
};
console.log("error", error);
console.log("rect", rect);
}
let navBarHeight = "";
if (!systemInfo.statusBarHeight) {
//开启wifi和打电话下
systemInfo.statusBarHeight =
systemInfo.screenHeight - systemInfo.windowHeight - 20;
navBarHeight = (function () {
let gap = rect.top - systemInfo.statusBarHeight;
return 2 * gap + rect.height;
})();
systemInfo.statusBarHeight = 0;
systemInfo.navBarExtendHeight = 0; //下方扩展4像素高度 防止下方边距太小
} else {
navBarHeight = (function () {
let gap = rect.top - systemInfo.statusBarHeight;
return systemInfo.statusBarHeight + 2 * gap + rect.height;
})();
if (ios) {
systemInfo.navBarExtendHeight = 4; //下方扩展4像素高度 防止下方边距太小
} else {
systemInfo.navBarExtendHeight = 0;
}
}
systemInfo.navBarHeight = navBarHeight; //导航栏高度不包括statusBarHeight
systemInfo.capsulePosition = rect; //右上角胶囊按钮信息bottom: 58 height: 32 left: 317 right: 404 top: 26 width: 87 目前发现在大多机型都是固定值 为防止不一样所以会使用动态值来计算nav元素大小
systemInfo.ios = ios; //是否ios
uni.globalSystemInfo = systemInfo; //将信息保存到全局变量中,后边再用就不用重新异步获取了
//console.log('systemInfo', systemInfo);
return systemInfo;
}
}
let globalSystemInfo = getSystemInfo();
console.log(globalSystemInfo, "globalSystemInfo");
const store = useStore();
const props = defineProps({
extClass: "",
background: { type: String, default: "#fff" }, //导航栏背景
color: {
type: String,
default: "#333",
},
title: {
type: String,
default: "",
},
searchText: {
type: String,
default: "点我搜索",
},
searchBar: {
type: Boolean,
default: false,
},
back: {
type: Boolean,
default: true,
},
home: {
type: Boolean,
default: false,
},
iconTheme: {
type: String,
default: "",
},
});
const setStyle = (systemInfo) => {
const {
statusBarHeight,
navBarHeight,
capsulePosition,
navBarExtendHeight,
ios,
windowWidth,
} = systemInfo;
const { back, home, title, color } = props;
console.log(back,systemInfo, "back");
let rightDistance = windowWidth - capsulePosition.right; //胶囊按钮右侧到屏幕右侧的边距
console.log(rightDistance, "rightDistance");
let leftWidth = windowWidth - capsulePosition.left; //胶囊按钮左侧到屏幕右侧的边距
let navigationbarinnerStyle = [
`color:${color}`,
`height:${navBarHeight + navBarExtendHeight}px`,
`padding-top:${statusBarHeight}px`,
`padding-right:${leftWidth}px`,
`padding-bottom:${navBarExtendHeight}px`,
].join(";");
let navBarLeft = [];
if ((back && !home) || (!back && home)) {
navBarLeft = [
`width:${capsulePosition.width}px`,
`height:${capsulePosition.height}px`,
`margin-left:0px`,
`margin-right:${rightDistance}px`,
].join(";");
} else if ((back && home) || title) {
navBarLeft = [
`width:${capsulePosition.width}px`,
`height:${capsulePosition.height}px`,
`margin-left:${rightDistance}px`,
].join(";");
} else {
navBarLeft = [`width:auto`, `margin-left:0px`].join(";");
}
const topHeight = navBarHeight + navBarExtendHeight;
console.log(topHeight, "topHeight");
store.commit("global/SET_NAV_BAR_HEIGHT", topHeight);
return {
navigationbarinnerStyle,
navBarLeft,
navBarHeight,
capsulePosition,
navBarExtendHeight,
ios,
rightDistance,
};
};
const state = reactive({
configStyle: setStyle(globalSystemInfo),
});
const { configStyle } = toRefs(state);
const {
navigationbarinnerStyle,
navBarLeft,
navBarHeight,
capsulePosition,
navBarExtendHeight,
ios,
rightDistance,
} = state.configStyle;
console.log(navBarLeft, "navBarLeft");
const handleBackClick = () => {
if (_isFunction(props.onBack)) {
props.onBack();
} else {
const pages = getCurrentPages();
if (pages.length >= 2) {
uni.navigateBack({
delta: props.delta,
});
}
}
};
const handleGoHomeClick = () => {
if (_isFunction(props.onHome)) {
props.onHome();
}
};
const handleSearchClick = () => {
if (_isFunction(props.onSearch)) {
props.onSearch();
}
};
操作步骤
编译运行
预期结果
编译运行获取 setStyle
函数中 systemInfo
为一个设备类型对象
实际结果
编译运行获取 setStyle
函数中 systemInfo
为一个 Promise 函数
bug 描述
运行编译到小程序后,获取设备信息为 Promise 函数
感谢反馈,此bug并非是getSystemInfoSync的Bug。问题出在下面这几行代码
if (uni.globalSystemInfo && !uni.globalSystemInfo.ios) {
return uni.globalSystemInfo;
}
目前这个bug会导致访问uni上不存在的属性也会返回一个方法,预计在4.51-alpha(下个alpha)修复
在uni-app最新版本4.45中,如果你遇到uni.getSystemInfoSync
并未按预期同步获取设备信息的问题,这可能是由于多种原因导致的,比如API的调用时机、缓存机制或者是框架内部的bug。不过,通常uni.getSystemInfoSync
应当是一个同步调用,用于立即获取设备信息。
为了确保你能够正确获取设备信息,并且在遇到异步行为时有一个替代方案,下面提供一个示例代码,展示如何使用uni.getSystemInfoSync
以及如何在需要时回退到异步方法uni.getSystemInfo
。
示例代码
// 使用同步方法获取设备信息
try {
const systemInfo = uni.getSystemInfoSync();
console.log('同步获取设备信息成功:', systemInfo);
// 在这里使用获取到的设备信息
} catch (error) {
console.error('同步获取设备信息失败:', error);
// 如果同步方法失败,尝试使用异步方法
uni.getSystemInfo({
success: (res) => {
console.log('异步获取设备信息成功:', res);
// 在这里使用异步获取到的设备信息
},
fail: (err) => {
console.error('异步获取设备信息失败:', err);
// 处理获取设备信息失败的逻辑
}
});
}
注意事项
- 错误处理:在同步调用失败时,使用
try...catch
结构捕获异常,并尝试异步调用。 - API调用时机:确保你的代码在合适的生命周期钩子或事件处理函数中调用这些API,避免在组件未完全加载时调用导致失败。
- uni-app和微信小程序的兼容性:检查
uni-app
和微信小程序的官方文档,确认当前使用的API版本和调用方式是否符合最新规范。 - 缓存机制:理解并考虑
uni-app
或微信小程序的缓存机制,这可能会影响你获取设备信息的实时性。 - 框架和依赖更新:确保你的
uni-app
框架和所有相关依赖都是最新版本,以避免已知的bug或不兼容问题。
通过上述代码示例和注意事项,你应该能够在大多数情况下正确获取设备信息,同时处理可能的异常情况。如果问题依旧存在,建议查阅uni-app
的官方社区或提交issue寻求官方支持。