uniappX——uts+uniappX踩坑记录(vue3项目
杂记:
web-view方面
内嵌html使用web-view时,直接用
uni.postMessage({
data: {
action: 'message' // 你要传的信息
}
});
示例上写的是用
document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'postMessage'
}
});
});
注意点:监听'UniAppJSBridgeReady, 有时候会失败,一直不触发,检查本地html文件放在hybrid文件夹里面,如:hybrid/html/js/xxx.js, hybrid/html/just.html
记得在html文件最上面先引入uni.webview.1.5.5.js,版本要是1.5.4及以上的
最后接收的app内的onmessage函数,接收类型一定要对,如UniWebViewMessageEvent或者UniWebViewErrorEvent
const handlePostMessage = (event: UniWebViewMessageEvent) => {}
若要兼容PC端,需要在声明周期mounted手动加一个监听:
// 进入时加监听,handlePostMessage监听方法
onMounted(() => {
window.addEventListener('message', handlePostMessage);
})
// 离开时卸载监听
onUnmounted(() => {
window.removeEventListener('message', handlePostMessage);
});
uts语法方面
1.有返回值的,一定要在函数定义时定义返回值类型!
2.循环注意,有时候你直接在箭头函数定义时用as断言它的类型,写循环可能报错(有时候也不报错),比如:
arr.map((item:string)=>{})
不行改成
arr.map((item)=>{
console.log(item as string | null )
})
(如果报错请注意打印的时候是否有声明的变量,多半是声明变量未处理null值逻辑)
3.关于number的大小对比
转换成Float再去对比大小,用parseFloat方法。如:
if(parseFloat((reqData.value['repayPrincipal']).toString() as string) > parseFloat(formModel.value['psRemPrcp'] as string)){}
注意: 结果要toFixed截留2位小数最好。
4. 有时候会报错null什么什么的,大概率是你定义的对象 as 声明了某个属性如string,但是最后未找到,比如:
const aoo = data['item'] as UTSJSONObject
console.log(aoo['money'] as number)
如果接口返回空什么的,这里就会直接报错
不要在打印等地方用属性不给空选项!
安全使用!! 声明时记得带null,上面代码安全使用应该是:
const aoo = data['item'] as UTSJSONObject|null ?? {}
let money = aoo['money'] as number|null ?? 0
// 这是安全使用所有数据,在给方法传参等时候都要注意这种写法
console.log(money)
5. 不要依靠类型推断,有些打包会报错:
如:
let a = {}; // 这个不对,运行可以但是打包会报错,也许之后会修复
let a = {} as UTSJSONObject // 这个 对了
uts最近更新,不用一定要定义函数的返回值类型,如:
// 原来必须主动声明返回string类型,function test(): string,现在可以省略,编译器会自动推导
// 支持箭头函数、函数声明、函数表达式、类方法的返回值类型推导
function test() {
return "test"
}
顺便放几个常用循环和计算,监听方法的示例:
计算属性:
const showBtn = computed((): boolean => tabs.value == '1')
watch监听:
watch(
(): string => tabs.value as string,
(newValue: string) => {
if (newValue === '1') {
const op = {
title: '勾选',
key: 'checkEd',
width: '70rpx',
} as xTableColumns
columnsData.value.unshift(op)
} else {
if (columnsData.value[0]['key'] === 'checkEd') {
columnsData.value.splice(0, 1)
}
}
},
{
immediate: true,
deep: true, // 开启深度监听
},
)
filter循环:
checkedValues.value = checkedValues.value.filter((itemTT: string): boolean => !iop.includes(itemTT))
注意,有时候会报错Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type UTSArray<UTSJSONObject>?
多半是你的循环值checkedValues.value可能为空或者筛选后的值可能为空null,你又将这个空的值做了push等处理。保险处理方法是加??,如:
const filteredArray = selectedIndices.value?.filter((itemTs: UTSJSONObject):boolean => {
return itemTs['parentCode'] != 'effectDt'; // 过滤掉 parentCode 为 'effectDt' 的对象
}) ?? [];
filteredArray.push(option)
selectedIndices.value = filteredArray;
默认没找到就给个空数组,其他循环也是有同样的问题,照着处理就行。
some循环:
const dect = iop.some((itemTT: string): boolean => checkedValues.value.includes(itemTT))
map循环:
let chooseFifter = chooseData.value.map((item): UTSJSONObject => {
let op = { materialsTaskId: item['materialsTaskId'], approvalRecordId: item['approvalRecordId'] }
return op;
})
forEach循环:
dataNow.forEach((item: UTSJSONObject) => {
item['metarils'] = [] as Array<UTSJSONObject>
})
datas?.forEach((itemTs: UTSJSONObject, index: number) => {
if (itemTs['approvalTaskId'] === soure['approvalTaskId']) {
found = true
removeIndex = index
}
})
JSON的转换:
const ops = JSON.parse(uni.getStorageSync('loginUserInfo') as string)
let params = {}
params['userType'] = (ops as UTSJSONObject)['userType'] as string
注意点:这个语言和ts一样甚至比ts更要求类型(一错了就卡死),尤其是你用了组件库,要去看好它们组件库里面定义的各个传参类型。若不一致,可能不会报错,但你会得到一个空的数组或对象。要引入,如:
import { xTableColumns } from '@/uni_modules/tmx-ui/interface.uts'
import { FORM_RULE, FORM_SUBMIT_RESULT } from '@/uni_modules/tmx-ui/interface.uts'
基本上出问题,十有八九是你类型定义没对或者你声明的类型和编辑器推断的不一样,或者你的类型没引入。
关于ref
因为我是vue3,对一个组件用ref这种方式获取实例的话,你需要知道这个组件的类型,如:
<z-paging-x ref="pagingX" :fixed="false" v-model="dataList" @query="queryList" show-back-to-top>
const pagingX = ref<ZPagingXComponentPublicInstance | null>(null)
ZPagingXComponentPublicInstance 就是我们ref z-pading-x 这个组件时 要声明的类型
类似的还有:
<x-form v-model="reqData" ref="formRef" :error-auto-page="false">
const formRef = ref<XFormComponentPublicInstance | null>(null)
有时候你用UTSJSONObject代替它特有类型不会报错,但是你只能得到空数组或对象。
ref定义变量时要先定义类型,在括号接默认值
注意:
你用ref后,若定义了数组对象等,你的.value去访问时 还要去as它的类型:
;(pagingX.value as ZPagingXComponentPublicInstance).reload()
const datas: Array<UTSJSONObject> = chooseData.value as Array<UTSJSONObject>
(): string => tabs.value as string,
注意:uts这个语言,不太建议你将赋值和定义类型合并一条代码。
自定义组件如何用ref
ComponentPublicInstance 这是自定义组件默认的格式。如:
<compent @onCheck="slideVerifySuccess" ref="verifyRef"></compent>
// 引入
import compent from './commonPage/compent .uvue'
// 赋值
const verifyRef = ref<ComponentPublicInstance | null>(null)
到这其实就可以用了,但是为了简便运行,建议你封装一个函数
通过$callMethod(funName, funParams)这种方法去运行。
普通标签view等用ref
主要是声明的类型不一样,你用view等时,他是一个element标签,所以你需要用它内置的UniElement 类型
如:
<view id="bigImgRef" ref="bigImgRef">
<image class="fulled" mode="widthFix" v-if="bigImageUrl != ''"
:src="bigImageUrl"
:preview="false"></image>
</view>
const bigImgRef = ref<UniElement | null>(null)
// 调用时bigImgRef.value接属性或方法
uts中调用子组件方法
首先需要在子组件中将方法暴露(用defineExpose)出来,这样外面的ref才能获取到你的方法,
const setVal= () => {
calculateApi(); // 调用子组件内的其他方法
}
defineExpose({
onBeforeSubmit,
clearType,
setVal,
})
然后在外面获取时,先调用uniapp方法获取到proxy
const instance = getCurrentInstance()!.proxy!
然后下面是使用,用$callMethod
const childFun = instance.$refs['settleTypeCom'] as ComponentPublicInstance
childFun!.$callMethod('setVal', val) // val是传给子组件方法的参数
注意:这里的ref要定义类型是通配的组件类型:ComponentPublicInstance
变量的定义
你可以
let op:string = (state.value as UTSJSONObject)['name'] as string;
等价于:
let op = (state.value as UTSJSONObject)['name'] as string;
注意点:有时候报错会很奇怪,你找不到时记得看看自己的;号有没有加好。有时候可以加你定义前,防止出错:
;(dataList.value as Array<UTSJSONObject>)[index]['metarils'] = data['list']
any这个类型,不建议用,有很多奇奇怪怪的问题,你接收后端传来的数据时可以先用any,后面再自己拆分。
关于getXXX方法,
如:data.getArray('list') as Array<UTSJSONObject>
还有getString等等,就相当于你得到这个变量时就给他定义了类型,但我不太用这个。文档说这是更安全访问的方式。
条件判断比较的坑
比如:if(a === '1')
它可能永远为false,原因可能是:
1.a是某个UTSJSONObject对象的属性,借于uts的自动类型断言来定义的类型,到这判断类型时就不对了。
2.a没用类型断言,为any
建议这类判断,统一在外定义特点类型的变量后,用该变量判断,或者别用===。
如:if(a == '1')
注意: !== 也是一样的,建议用!=
先写道这,后面遇到了再长期更新...
更多推荐



所有评论(0)