uniapp编译小程序typeof不支持的问题
使用uniapp框架,编译后发现出现如下报错。
对 wxml 文档进行格式化,使用删代码调试的方法最终定位到了报错的内容为以下代码引起
<block wx:if="{{typeof 'a'==='string'&&item.m1==='object'}}">
再进一步排查,发现是对行内判断 typeof 不支持微信小程序造成的。
在 JavaScript 中,typeof 是一个运算符,用于返回一个表示操作数的类型的字符串。它可以用于检查一个值的数据类型,例如:
typeof 5 // 返回 "number" typeof "hello" // 返回 "string"
typeof 运算符可以用于检查任何数据类型,包括原始类型(如数字、字符串、布尔值等)和复杂类型(如对象、数组、函数等)。
然而,由于各个平台对 JavaScript 的支持情况不同,因此 UniApp 中的 JavaScript 代码并不能在所有平台上运行。例如,在微信小程序中,您可能无法使用某些 JavaScript 特性,包括行内 typeof 运算符。
最终解决办法为定义一个方法,在行内调用方法而避免直接调用 typeof。如下所示
<block wx:if="{{getType('a')==='string'&&item.m1==='object'}}">
在页面中定义函数
export default{
// ...
methods: {
getType(v){
return typeof v;
}
}
// ...
} 使用uniapp框架,编译后发现出现如下报错。
对 wxml 文档进行格式化,使用删代码调试的方法最终定位到了报错的内容为以下代码引起
<block wx:if="{{typeof 'a'==='string'&&item.m1==='object'}}">
再进一步排查,发现是对行内判断 typeof 不支持微信小程序造成的。
在 JavaScript 中,typeof 是一个运算符,用于返回一个表示操作数的类型的字符串。它可以用于检查一个值的数据类型,例如:
typeof 5 // 返回 "number" typeof "hello" // 返回 "string"
typeof 运算符可以用于检查任何数据类型,包括原始类型(如数字、字符串、布尔值等)和复杂类型(如对象、数组、函数等)。
然而,由于各个平台对 JavaScript 的支持情况不同,因此 UniApp 中的 JavaScript 代码并不能在所有平台上运行。例如,在微信小程序中,您可能无法使用某些 JavaScript 特性,包括行内 typeof 运算符。
最终解决办法为定义一个方法,在行内调用方法而避免直接调用 typeof。如下所示
<block wx:if="{{getType('a')==='string'&&item.m1==='object'}}">
在页面中定义函数
export default{
// ...
methods: {
getType(v){
return typeof v;
}
}
// ...
} 收起阅读 »
实现在windows、linux下上传ios app到App Store
实现在windows、linux下上传ios app到App Store
我们知道发布一个app,一般是用到苹果的application loader助手上传应用,用过的都知道使用起来很繁琐,经常出错。而且只能运行在mac系统上,需要一定的硬件条件。
前段时间发现了一个上架的辅助工具Appuploader,可以实现在windows,linux或mac上,不需要应用程序加载器和mac计算机,就可以发布app到app store,试用了下,感觉不错,分享给各位开发者,方便大家。
Appuploader算是一个专门为IOS app上架的开发助手,可以快速,轻松地生成ios开发证书,不需要钥匙串助手; appuploader还可以批量上传屏幕截图并将ipa文件上传到Apple商店。很方便的生成证书和配置文件的,快速的上架app,提升效率的辅助工具,现在可以免费使用,分享给大家。
实现在windows、linux下上传ios app到App Store
我们知道发布一个app,一般是用到苹果的application loader助手上传应用,用过的都知道使用起来很繁琐,经常出错。而且只能运行在mac系统上,需要一定的硬件条件。
前段时间发现了一个上架的辅助工具Appuploader,可以实现在windows,linux或mac上,不需要应用程序加载器和mac计算机,就可以发布app到app store,试用了下,感觉不错,分享给各位开发者,方便大家。
Appuploader算是一个专门为IOS app上架的开发助手,可以快速,轻松地生成ios开发证书,不需要钥匙串助手; appuploader还可以批量上传屏幕截图并将ipa文件上传到Apple商店。很方便的生成证书和配置文件的,快速的上架app,提升效率的辅助工具,现在可以免费使用,分享给大家。
收起阅读 »hbuilder 的bug真多
明明选中着项目,运行时候说没有选中,非得再点一下,点的时候又把项目折叠,还得点开,麻烦死了。
明明选中着项目,运行时候说没有选中,非得再点一下,点的时候又把项目折叠,还得点开,麻烦死了。
官方tabbar扩展、完全自定义、点击带动画效果、可设置字体粗细、隐藏图标或文本、图标或文本大小、选中和未选中的样式等等
官方tabbar扩展、完全自定义、点击带动画效果、可设置字体粗细、隐藏图标或文本、图标或文本大小、选中和未选中的样式等等:https://ext.dcloud.net.cn/plugin?id=10343
官方tabbar扩展、完全自定义、点击带动画效果、可设置字体粗细、隐藏图标或文本、图标或文本大小、选中和未选中的样式等等:https://ext.dcloud.net.cn/plugin?id=10343
收起阅读 »在 @vue/composition-api 中使用 createSelectorQuery 的 this 问题
- 当你在 @vue/composition-api 使用 createSelectorQuery 时获取不到 this, 则使用 getCurrentInstance 替换
- 演示代码:
import { getCurrentInstance } from '@vue/composition-api'
export default {
setup() {
const app = getCurrentInstance()
uni
.createSelectorQuery()
.in(app.proxy)
.select('#myCanvas')
.node(data => {
console.log(data) // 输出:{ nodeCanvasType: "2d", node: Cy }
})
.exec()
}
}
- 如果是vue3则去掉 proxy 即可
import { getCurrentInstance } from '@vue/composition-api'
export default {
setup() {
const app = getCurrentInstance()
uni
.createSelectorQuery()
.in(app)
.select('#myCanvas')
.node(data => {
console.log(data) // 输出:{ nodeCanvasType: "2d", node: Cy }
})
.exec()
}
} - 当你在 @vue/composition-api 使用 createSelectorQuery 时获取不到 this, 则使用 getCurrentInstance 替换
- 演示代码:
import { getCurrentInstance } from '@vue/composition-api'
export default {
setup() {
const app = getCurrentInstance()
uni
.createSelectorQuery()
.in(app.proxy)
.select('#myCanvas')
.node(data => {
console.log(data) // 输出:{ nodeCanvasType: "2d", node: Cy }
})
.exec()
}
}
- 如果是vue3则去掉 proxy 即可
import { getCurrentInstance } from '@vue/composition-api'
export default {
setup() {
const app = getCurrentInstance()
uni
.createSelectorQuery()
.in(app)
.select('#myCanvas')
.node(data => {
console.log(data) // 输出:{ nodeCanvasType: "2d", node: Cy }
})
.exec()
}
} 收起阅读 »
Some App Tech Support
一、软件介绍
名称:轻速云
类型:软件工具
二、功能
轻速云在线教育云平台,提供在线考试系统、在线培训系统、网上考试系统、知识竞赛等多方面的培训考试软件服务,超高并发,支持电脑、Pad和手机三端使用,并且可以实现微信考试、钉钉考试或与其他App无缝衔接,我们以更专业可靠的实力让您组织在线培训考试变得简单方便。
三、Getting Support:
邮箱: disanfang@qingsuyun.com
一、软件介绍
名称:轻速云
类型:软件工具
二、功能
轻速云在线教育云平台,提供在线考试系统、在线培训系统、网上考试系统、知识竞赛等多方面的培训考试软件服务,超高并发,支持电脑、Pad和手机三端使用,并且可以实现微信考试、钉钉考试或与其他App无缝衔接,我们以更专业可靠的实力让您组织在线培训考试变得简单方便。
三、Getting Support:
邮箱: disanfang@qingsuyun.com
收起阅读 »VUE中定义的变量的生命期(个人测试, 如表述有误,欢迎指正)
我做了三个单元
common/myUtils.js
pages/index/index.vue (默认)
pages/page2/page2.vue
以下例子是为了证明:
这个例子,主要是证明:
1>.一个vue页面中,在script第一级中(非export),定义的变量,对自身是有效的
2>.即便这个vue页面关闭后,再打开,这个变量值仍是上次的值,
3>.如果你要避免这种情况, 你就要在onload或onshow中,初始化了一下
4>.第2个vue页面是无法访问到第1个vue页面的值(即使你已在第1页中已export了这个变量)
5>.但是,如果你在目录common中的js文件中定义了一个变量,则在vue中import一下,就可以访问\
6>.但也仅限于读取, 无法写入更改这个变量的值,
7>.如果你实在想搞个全局变量,可以用uni.setStorageSync,uni.getStorageSync来实现
common/myUtils.js
var kkkk='hello';
export{
kkkk
} 我做了三个单元
common/myUtils.js
pages/index/index.vue (默认)
pages/page2/page2.vue
以下例子是为了证明:
这个例子,主要是证明:
1>.一个vue页面中,在script第一级中(非export),定义的变量,对自身是有效的
2>.即便这个vue页面关闭后,再打开,这个变量值仍是上次的值,
3>.如果你要避免这种情况, 你就要在onload或onshow中,初始化了一下
4>.第2个vue页面是无法访问到第1个vue页面的值(即使你已在第1页中已export了这个变量)
5>.但是,如果你在目录common中的js文件中定义了一个变量,则在vue中import一下,就可以访问\
6>.但也仅限于读取, 无法写入更改这个变量的值,
7>.如果你实在想搞个全局变量,可以用uni.setStorageSync,uni.getStorageSync来实现
common/myUtils.js
var kkkk='hello';
export{
kkkk
} 收起阅读 »
plus.cache.clear实现白名单效果保存localStorage
实现方法很简单,使用前把所有localStorage的key和值存储到两个数组,plus.cache.clear清除完成后利用循环重新写入即可
function plusReady() {
var key = []
var key_ = []
for (let i = 0; i < localStorage.length; i++) {
key.push(localStorage.key(i)) //获取所有localStorage的key
key_.push(localStorage.getItem(localStorage.key(i))) //获取所有localStorage的值
length = localStorage.length //获取所有localStorage数量
if (i == localStorage.length - 1) {
plus.nativeUI.confirm("确定清除缓存数据?", function (e) {
if (e.index == 0) {
plus.cache.clear(function () { });//清除缓存
plus.nativeUI.toast('已清除缓存');
for (let a = 0; a < length; a++) {
localStorage.setItem(key[a], key_[a]) //清除完毕后利用重新写入localStorage
}
}
}, "清除缓存数据", ["确定", "取消"]);
}
}
}
if (window.plus) {
plusReady();
} else {
document.addEventListener('plusready', plusReady, false);
} 实现方法很简单,使用前把所有localStorage的key和值存储到两个数组,plus.cache.clear清除完成后利用循环重新写入即可
function plusReady() {
var key = []
var key_ = []
for (let i = 0; i < localStorage.length; i++) {
key.push(localStorage.key(i)) //获取所有localStorage的key
key_.push(localStorage.getItem(localStorage.key(i))) //获取所有localStorage的值
length = localStorage.length //获取所有localStorage数量
if (i == localStorage.length - 1) {
plus.nativeUI.confirm("确定清除缓存数据?", function (e) {
if (e.index == 0) {
plus.cache.clear(function () { });//清除缓存
plus.nativeUI.toast('已清除缓存');
for (let a = 0; a < length; a++) {
localStorage.setItem(key[a], key_[a]) //清除完毕后利用重新写入localStorage
}
}
}, "清除缓存数据", ["确定", "取消"]);
}
}
}
if (window.plus) {
plusReady();
} else {
document.addEventListener('plusready', plusReady, false);
} 收起阅读 »
关于我的插件easyEcharts1.0.5更新新版本报插件名称问题
为什么我的easy-Echarts1.0.5更新新版本一直提示下面附件的问题,单个组件已符合命名规范了。官方请告知详情
为什么我的easy-Echarts1.0.5更新新版本一直提示下面附件的问题,单个组件已符合命名规范了。官方请告知详情
如何使用 uni-app 30分钟快速开发即时通讯应用|开发者活动
“一套代码,多端运行”是很多开发团队的梦想,基于 uni-app 跨平台框架支持 iOS、Android、Web以及各种小程序并支持平台间互通,快速实现搭建多端即时通讯功能,降低开发难度,提升开发效率。
12月13日 晚 19:00,环信线上公开课《使用 uniapp 30分钟快速开发即时通讯应用》为题,讲解多端 uni-app 基础框架知识及搭建即时通讯功能项目实战技巧,掌握开发步骤及思路,大大增强代码复用率,提升效率。来直播间 get 环信 IM 的正确打开方式!
一、时间地点
活动时间:12 月 13 日(星期二)19:00-20:00
活动地点:线上直播
二、演讲大纲
uni-app 跨平台框架介绍
使用uni-app 生成 Android&iOS 应用
如何搭建自己的即时通讯应用
IM实战篇-uni-app 经典问题答疑
三、活动报名
报名链接:报名表单
“一套代码,多端运行”是很多开发团队的梦想,基于 uni-app 跨平台框架支持 iOS、Android、Web以及各种小程序并支持平台间互通,快速实现搭建多端即时通讯功能,降低开发难度,提升开发效率。
12月13日 晚 19:00,环信线上公开课《使用 uniapp 30分钟快速开发即时通讯应用》为题,讲解多端 uni-app 基础框架知识及搭建即时通讯功能项目实战技巧,掌握开发步骤及思路,大大增强代码复用率,提升效率。来直播间 get 环信 IM 的正确打开方式!
一、时间地点
活动时间:12 月 13 日(星期二)19:00-20:00
活动地点:线上直播
二、演讲大纲
uni-app 跨平台框架介绍
使用uni-app 生成 Android&iOS 应用
如何搭建自己的即时通讯应用
IM实战篇-uni-app 经典问题答疑
三、活动报名
报名链接:报名表单
收起阅读 »【通知权限】app判断通知权限是否开启,前往系统设置页面开关通知权限
来源:https://ext.dcloud.net.cn/plugin?id=789
// 判断通知权限是否开启
function isOn() {
// #ifdef APP-PLUS
if (plus.os.name == "Android") {
var main = plus.android.runtimeMainActivity();
var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
if (NotificationManagerCompat == null) {
NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
}
var areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
return areNotificationsEnabled;
} else if (plus.os.name == "iOS") {
var isIosOn = undefined;
var types = 0;
var app = plus.ios.invoke("UIApplication", "sharedApplication");
var settings = plus.ios.invoke(app, "currentUserNotificationSettings");
if (settings) {
types = settings.plusGetAttribute("types");
plus.ios.deleteObject(settings);
} else {
types = plus.ios.invoke(app, "enabledRemoteNotificationTypes");
}
plus.ios.deleteObject(app);
isIosOn = 0 != types;
return isIosOn;
}
// #endif
}
// 前往系统设置页面开启或关闭通知权限
function switchPushPermissions() {
// #ifdef APP-PLUS
let title = isOn() ? "通知权限关闭提醒" : "通知权限开启提醒";
let content = isOn()
? "通知权限已开启,是否前往设置关闭?"
: "您还没有开启通知权限,无法接受到消息通知,是否前往设置?";
// 打开安卓系统设置页面
let openAndroidSetting = () => {
var main = plus.android.runtimeMainActivity();
var pkName = main.getPackageName();
var uid = main.getApplicationInfo().plusGetAttribute("uid");
var Intent = plus.android.importClass("android.content.Intent");
var Build = plus.android.importClass("android.os.Build");
//android 8.0引导
if (Build.VERSION.SDK_INT >= 26) {
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("android.provider.extra.APP_PACKAGE", pkName);
} else if (Build.VERSION.SDK_INT >= 21) {
//android 5.0-7.0
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("app_package", pkName);
intent.putExtra("app_uid", uid);
} else {
//(<21)其他--跳转到该应用管理的详情页
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
}
// 跳转到该应用的系统通知设置页
main.startActivity(intent);
};
// 打开苹果系统设置页面
let openIOSSetting = () => {
var app = plus.ios.invoke("UIApplication", "sharedApplication");
var setting = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
plus.ios.invoke(app, "openURL:", setting);
plus.ios.deleteObject(setting);
plus.ios.deleteObject(app);
// ios18跳转不过去的解决方案
// 方案一:使用uni.openAppAuthorizeSetting(),文档地址:https://uniapp.dcloud.net.cn/api/system/openappauthorizesetting.html
// 方案二:待验证,AI生成;来源评论区:iOS 18以后,openURL:完全被弃用,需要用openURL:options:completionHandler:替代。
// var app = plus.ios.invoke("UIApplication", "sharedApplication");
// var url;
// // 获取安全 URL(iOS 8+)
// if (plus.ios.invoke("UIApplication", "respondsToSelector:", "openSettingsURLString")) {
// var urlString = plus.ios.invoke("UIApplication", "openSettingsURLString");
// url = plus.ios.invoke("NSURL", "URLWithString:", urlString);
// } else {
// url = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
// }
// // 判断新 API 可用性(iOS 10+)
// var supportsNewAPI = plus.ios.invoke(app, "respondsToSelector:", "openURL:options:completionHandler:");
// if (supportsNewAPI) {
// var options = plus.ios.newObject("NSDictionary");
// var completion = plus.ios.newBlock(function(success) {
// console.log("跳转结果:" + success);
// if (!success) {
// plus.nativeUI.toast("无法打开设置,请手动前往");
// }
// }, "v@:B");
// plus.ios.invoke(app, "openURL:options:completionHandler:", url, options, completion);
// plus.ios.deleteObject(completion);
// } else {
// if (plus.ios.invoke(app, "canOpenURL:", url)) {
// plus.ios.invoke(app, "openURL:", url);
// } else {
// throw new Error("当前系统不支持跳转设置");
// }
// }
// plus.ios.deleteObject(url);
// plus.ios.deleteObject(app);
};
// 弹窗提醒开通或关闭权限,点击确认后,跳转到系统设置页面进行设置
uni.showModal({
title: title,
content: content,
showCancel: true,
confirmColor: "#ff903f",
success: (res) => {
if (res.confirm) {
if (plus.os.name == "Android") {
openAndroidSetting();
} else if (plus.os.name == "iOS") {
openIOSSetting();
}
}
},
});
// #endif
}
export default {
isOn,
switchPushPermissions,
};
↓↓↓ 各位大佬点点赞
来源:https://ext.dcloud.net.cn/plugin?id=789
// 判断通知权限是否开启
function isOn() {
// #ifdef APP-PLUS
if (plus.os.name == "Android") {
var main = plus.android.runtimeMainActivity();
var NotificationManagerCompat = plus.android.importClass("android.support.v4.app.NotificationManagerCompat");
if (NotificationManagerCompat == null) {
NotificationManagerCompat = plus.android.importClass("androidx.core.app.NotificationManagerCompat");
}
var areNotificationsEnabled = NotificationManagerCompat.from(main).areNotificationsEnabled();
return areNotificationsEnabled;
} else if (plus.os.name == "iOS") {
var isIosOn = undefined;
var types = 0;
var app = plus.ios.invoke("UIApplication", "sharedApplication");
var settings = plus.ios.invoke(app, "currentUserNotificationSettings");
if (settings) {
types = settings.plusGetAttribute("types");
plus.ios.deleteObject(settings);
} else {
types = plus.ios.invoke(app, "enabledRemoteNotificationTypes");
}
plus.ios.deleteObject(app);
isIosOn = 0 != types;
return isIosOn;
}
// #endif
}
// 前往系统设置页面开启或关闭通知权限
function switchPushPermissions() {
// #ifdef APP-PLUS
let title = isOn() ? "通知权限关闭提醒" : "通知权限开启提醒";
let content = isOn()
? "通知权限已开启,是否前往设置关闭?"
: "您还没有开启通知权限,无法接受到消息通知,是否前往设置?";
// 打开安卓系统设置页面
let openAndroidSetting = () => {
var main = plus.android.runtimeMainActivity();
var pkName = main.getPackageName();
var uid = main.getApplicationInfo().plusGetAttribute("uid");
var Intent = plus.android.importClass("android.content.Intent");
var Build = plus.android.importClass("android.os.Build");
//android 8.0引导
if (Build.VERSION.SDK_INT >= 26) {
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("android.provider.extra.APP_PACKAGE", pkName);
} else if (Build.VERSION.SDK_INT >= 21) {
//android 5.0-7.0
var intent = new Intent("android.settings.APP_NOTIFICATION_SETTINGS");
intent.putExtra("app_package", pkName);
intent.putExtra("app_uid", uid);
} else {
//(<21)其他--跳转到该应用管理的详情页
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
}
// 跳转到该应用的系统通知设置页
main.startActivity(intent);
};
// 打开苹果系统设置页面
let openIOSSetting = () => {
var app = plus.ios.invoke("UIApplication", "sharedApplication");
var setting = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
plus.ios.invoke(app, "openURL:", setting);
plus.ios.deleteObject(setting);
plus.ios.deleteObject(app);
// ios18跳转不过去的解决方案
// 方案一:使用uni.openAppAuthorizeSetting(),文档地址:https://uniapp.dcloud.net.cn/api/system/openappauthorizesetting.html
// 方案二:待验证,AI生成;来源评论区:iOS 18以后,openURL:完全被弃用,需要用openURL:options:completionHandler:替代。
// var app = plus.ios.invoke("UIApplication", "sharedApplication");
// var url;
// // 获取安全 URL(iOS 8+)
// if (plus.ios.invoke("UIApplication", "respondsToSelector:", "openSettingsURLString")) {
// var urlString = plus.ios.invoke("UIApplication", "openSettingsURLString");
// url = plus.ios.invoke("NSURL", "URLWithString:", urlString);
// } else {
// url = plus.ios.invoke("NSURL", "URLWithString:", "app-settings:");
// }
// // 判断新 API 可用性(iOS 10+)
// var supportsNewAPI = plus.ios.invoke(app, "respondsToSelector:", "openURL:options:completionHandler:");
// if (supportsNewAPI) {
// var options = plus.ios.newObject("NSDictionary");
// var completion = plus.ios.newBlock(function(success) {
// console.log("跳转结果:" + success);
// if (!success) {
// plus.nativeUI.toast("无法打开设置,请手动前往");
// }
// }, "v@:B");
// plus.ios.invoke(app, "openURL:options:completionHandler:", url, options, completion);
// plus.ios.deleteObject(completion);
// } else {
// if (plus.ios.invoke(app, "canOpenURL:", url)) {
// plus.ios.invoke(app, "openURL:", url);
// } else {
// throw new Error("当前系统不支持跳转设置");
// }
// }
// plus.ios.deleteObject(url);
// plus.ios.deleteObject(app);
};
// 弹窗提醒开通或关闭权限,点击确认后,跳转到系统设置页面进行设置
uni.showModal({
title: title,
content: content,
showCancel: true,
confirmColor: "#ff903f",
success: (res) => {
if (res.confirm) {
if (plus.os.name == "Android") {
openAndroidSetting();
} else if (plus.os.name == "iOS") {
openIOSSetting();
}
}
},
});
// #endif
}
export default {
isOn,
switchPushPermissions,
};
↓↓↓ 各位大佬点点赞
收起阅读 »









