最近写的一个IM即时通讯系统差不多算是完善了,在h5端调试着一般都没有什么很难搞的bug。然而就在昨天,将项目运行到模拟器时聊天界面获取历史记录消息并渲染在页面上时,却报了一堆很奇怪的错误
cid unmatched at view.umd.min.js:1
TypeError: Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method. at view.umd.min.js:1
当你在APP端运行时,如果出现这种报错信息,而在h5端又是正常的,这说明你的代码在使用对象属性时用到了一些未定义的属性,或者是属性值为null的。
出现错误的代码是在一个v-for循环中使用了我自定义的一个消息组件,用于显示消息页面的消息框,其中组件向外暴露了一个type属性,type的类型是boolean,在组件中用v-if,v-else来控制消息框居左还是居右,具体组件代码如下:
<template>
<view>
<view v-if="type">
<view class="message message-right">
<view class="message-right-status">
<u-loading-icon v-if="status === 'sending'" size="16"></u-loading-icon>
<u-icon v-if="status === 'fail'" name="error-circle-fill" size="16" color="#fa3534"></u-icon>
</view>
<view class="content content-right">
{{content}}
</view>
<view style="height: 80rpx;padding-right: 16rpx;">
<u-avatar v-if="avatar" :src="avatar"></u-avatar>
<u-avatar v-else :text="nickname.charAt(0)" randomBgColor></u-avatar>
</view>
</view>
</view>
<view v-else>
<view class="message message-left">
<view style="height: 80rpx;padding-left: 16rpx;">
<u-avatar v-if="avatar" :src="avatar"></u-avatar>
<u-avatar v-else :text="nickname.charAt(0)" randomBgColor></u-avatar>
</view>
<view class="content content-left">
{{content}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
props:{
//true时消息在右侧,即发送的消息,false时消息在左侧,即接收的消息
type:{
type: [Boolean],
default: false
},
nickname:{
type: [String,Number],
default: '私聊者昵称'
},
avatar:{
type: [String],
default: "/static/common/logo.png"
},
content:{
type: [String],
default: "消息内容"
},
status:{
type: [String],
default: 'none'
}
},
methods: {
}
}
</script>
<style>
.message-time{
text-align: center;
color: #959595;
font-size: 26rpx;
}
.message{
width: 100%;
display: flex;
}
.message-left{
justify-content: flex-start;
}
.message-right{
justify-content: flex-end;
}
.message-right-status{
display: flex;
align-items: flex-end;
padding-right: 16rpx;
}
.content{
max-width: 70%;
min-width: 7%;
margin-top: 40rpx;
word-wrap:break-word;
word-break:break-all;
padding: 14rpx 10rpx 14rpx 18rpx;
border-radius: 20rpx;
font-size: 32rpx;
min-height: 40rpx;
}
.content-left{
margin-left: 4rpx;
background-color: #FFFFFF;
color: #000000;
}
.content-right{
margin-right: 8rpx;
background-color: #3c9cff;
color: #FFFFFF;
}
</style>
在网上找的帖子都说这种报错是因为使用的对象属性不存在,或是给组件传值时传的值是null等等。
为此我将组件的属性的默认值都设置为有意义的字符串(除了type属性外,因为他的类型是boolean),一开始将组件的传值全部取掉,运行页面,获取历史记录,页面都是正常的,之后我就将要给组件传值的属性一一测试,最后发现其他属性都不会引起上述报错,唯独type
属性,后来我把type属性的类型改成string,number等发现均会引起报错,最后不得已,将这个消息组件拆成了两个组件,一个居左,一个居右。
不给组件传type值用于区分左右消息框,而是直接将原始组件拆分成两个。
未拆分前组件传值是这样的:
<scroll-view :style="{height: height+'px'}" :scroll-into-view="scrollIndex" scroll-y>
<view class="message-time" style="padding-top: 20rpx;">
{{allHistoryLoaded ? '没有更多的历史消息' : '下拉获取历史消息'}}
</view>
<view v-for="(item,index) in messages" :key="index" style="padding-top: 20rpx;" :id="`msg-${index+1}`"></view>
<my-msg
:type="item.senderMid == selfObj.memberId"
:avatar="item.senderMid == selfObj.memberId?selfObj.avatar:friendObj.avatar"
:nickname="item.senderMid == selfObj.memberId?selfObj.nickname:friendObj.nickname"
:content="item.content"
:status="item.status"></my-msg>
</view>
</scroll-view>
代码去除了一些无关紧要的事件绑定,这样直接传值type用于区分消息框的位置会导致报错,后改成两个组件后:
<scroll-view :style="{height: height+'px'}" :scroll-into-view="scrollIndex" scroll-y>
<view class="message-time" style="padding-top: 20rpx;">
{{allHistoryLoaded ? '没有更多的历史消息' : '下拉获取历史消息'}}
</view>
<view v-for="(item,index) in messages" :key="index" style="padding-top: 20rpx;" :id="`msg-${index+1}`">
<view v-if="item.senderMid == selfObj.memberId">
<my-msg-right :content="item.content" :status="item.status ? item.status: 'none'" :nickname="selfObj.nickname" :avatar="selfObj.avatar"></my-msg-right>
</view>
<view v-else>
<my-msg-left :content="item.content" :nickname="friendObj.nickname" :avatar="friendObj.avatar"></my-msg-left>
</view>
</view>
</scroll-view>
在需要传值的组件外部包一个view并且通过v-if来实现原来要的效果,这般操作下来,发现没有报错了,查看了uniapp官方对于v3编译器的支持发现,其对v-if,v-else是支持的,但是我遇到的情况却是不支持的,也不知道是为什么,也可能是我用的不规范,但好歹最后把问题解决了。
如果你也在uniapp的APP端测试遇到了cid unmatched at view.umd.min.js:1
的报错,可以先检查使用的对象属性是否存在,再看看传过去的值是否会是null,如果是组件传值建议花点时间对每个属性一一测试。