uni-app踩坑之自定义组件渲染问题
业务介绍
因为我一开始都是做的后端开发,然后之前的几个项目没前端我就学了1个多月的VUE硬上了还是个小白大佬勿喷,这次我公司要做一个小商店的小程序,之前一直都是用微信原生的开发工具开发这次想尝试一下使用uni-app,毕竟跨平台嘛哈哈哈哈
业务说明
做一个如此的tabs切换栏目
这个列表是List渲染的
我想就写成一个组件
然后props里传递一个数组过来
//部分代码
data() {
return {
itemList:[{text:"默认"},{text:"新品"},{text:"销量"},{text:"价格",sort:true,isUp:false}]
}
},
text属性代表的是标题 sort是否开启排序 isUp代表升序降序 如数组的第4个元素
组件代码
<template>
<view class="ui-goods-tabs">
<view class="ui-goods-tabs-item" v-for="(item,index) in itemList2" :style='{color:choiceIndex==index?"#000000":"#999"}' :key=index @click="choice(item,index)">
<text>{{item.text}}</text>
<view class="ui-all-center" v-if="item.sort">
<image :style='{display:choiceIndex!=index?"":"none"}' src="../static/svg/sort.svg"></image>
<image :style='{display:item.isUp&&choiceIndex==index?"":"none"}' src="/static/svg/sort_up.svg"></image>
<image :style='{display:!item.isUp&&choiceIndex==index?"":"none"}' src="../static/svg/sort_down.svg"></image>
</view>
</view>
</view>
</template>
首先说下这里为啥没用v-show渲染
emm因为之前确实用了v-show但是发现第4个元素排序切换无法使用,在H5上很正常但是在小程序上发现根本不走方法
methods:{
choice(e,i){
this.choiceIndex=i;
if(e.sort){
if("isUp" in e){
e.isUp=!e.isUp
this.$set(this.itemList2,i,e)
}else{
e.isUp=true
this.$set(this.itemList2,i,e)
}
}
this.$emit("clickItem",e)
}
},
我查了半天,有人说是因为微信的渲染原因造成,我看了下uni-app编译v-show确实如此,我也干脆改成样式切换把,随后发现还是无法切换 依旧是H5可行 小程序不行
贴下完整的组件代码
<template>
<view class="ui-goods-tabs">
<view class="ui-goods-tabs-item" v-for="(item,index) in itemList2" :style='{color:choiceIndex==index?"#000000":"#999"}' :key=index @click="choice(item,index)">
<text>{{item.text}}</text>
<view class="ui-all-center" v-if="item.sort">
<image :style='{display:choiceIndex!=index?"":"none"}' src="../static/svg/sort.svg"></image>
<image :style='{display:item.isUp&&choiceIndex==index?"":"none"}' src="/static/svg/sort_up.svg"></image>
<image :style='{display:!item.isUp&&choiceIndex==index?"":"none"}' src="../static/svg/sort_down.svg"></image>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
itemList:{
type:Array,
default:[]
}
},
data() {
return {
choiceIndex:0,
itemList2:[]
};
},
methods:{
choice(e,i){
this.choiceIndex=i;
if(e.sort){
if("isUp" in e){
e.isUp=!e.isUp
this.$set(this.itemList2,i,e)
}else{
e.isUp=true
this.$set(this.itemList2,i,e)
}
}
this.$emit("clickItem",e)
}
},
mounted() {
var _this = this;
_this.itemList2=_this.itemList
}
}
</script>
踩坑1:微信小程序无法直接操作props里的对象
首先一开始我直接用的从页面上传递过来的itemList进行的v-for循环,一切没问题,我以为后面的操作就和vue一样一切照旧.
后面在小程序的控制台了发现这个值并没有进行任何改变,随后我就干脆在data里加个itemList2
在mounted里进行赋值,然后真的就可以了,小程序端也可以正常操作.
但是第二个Bug又来了
踩坑2:uni-app自定义组件里的数组渲染的问题
这个问题解释起来很抽象,怎么说呢因为这个BUG在我的手机上会出现,但是在别人的手机上却没有这个问题,可能得换手机了吧哈哈哈
也就是我的第一个数组对象竟然没有渲染???直接是空的,微信开发者工具也是正常,但是我都用不了,用户怎么办呢,本着对用户负责的原则开始了找BUG之路
截图如下
这里arr的第一个值无法渲染出来 也就是我把v-for 循环的itemList改为itemList2之后出现的
但是我去点击其他的标签这个又会被渲染出来,我一开始以为是加载没出来的问题使劲刷新,结果有时候有有时候没有,这就很奇怪了,然后我试了各种方法都没有用但是别人的手机测试出来没有任何问题,我想应该和手机性能有关系把没有办法…
因为我一开始设置的choiceIndex=0 默认第一个 我以为是这里的问题,结果改成其他任何值都没有效果,
最后我想了一下在mounted里对choiceIndex重新进行赋值
mounted() {
var _this = this;
_this.itemList2=_this.itemList
this.choiceIndex=0
}
测试发现这个问题出现的概率变小了
随后我把默认值choiceIndex改为了-1或者其他值大概1%的概率出现
最后我加了个setTimeout 200毫秒的延迟最终搞定了这个问题
mounted() {
var _this = this;
_this.itemList2=_this.itemList
setTimeout(()=>{
this.choiceIndex=0
},200)
}
不过我解决的方法有点lo 还希望各位大佬指点一下 刚刚开始学uni-app