uni-app踩坑之自定義元件陣列渲染問題
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