問(wèn)題
今天在繼續(xù)復(fù)習(xí)uni-app項(xiàng)目時(shí),使用模擬器運(yùn)行時(shí),突然發(fā)現(xiàn)封裝的search組件樣式無(wú)法正常顯示,但是小程序頁(yè)面又是正常的,打包后真機(jī)也是一樣的結(jié)果。在uni-app的控制臺(tái)報(bào)如下錯(cuò)誤:
[Vue warn]: Error in render: “TypeError: Cannot read property ‘children’ of undefined”
TypeError: Cannot read property ‘children’ of undefined
問(wèn)題截圖
小程序界面搜索樣式正常
安卓界面運(yùn)行異常
問(wèn)題分析
這是分類(lèi)頁(yè)面中的源碼,其中my-search組件即為上方圖中的固定定位搜索框
<template>
<view>
<my-search ></my-search>
<view class="scrollContainer" >
<scroll-view scroll-y="true" class="leftScrollContainer" :style="{height: scrollHeight + 'px' }" :scroll-top="leftScrollTop">
<view :class="'firstCateItem ' + (index===currentSelectedIndex? 'active' :'') " v-for="(item1,index) in cateList" :key="index" @click="changeSelectedIndex(index)">
{{item1.cat_name}}
</view>
</scroll-view>
<scroll-view scroll-y="true" class="rightScrollContainer" :style="{height: scrollHeight + 'px'}" :scroll-top="rightScrollTop">
<view class="childCateContainer" v-for="(item2,index2) in cateList[currentSelectedIndex].children " :key="index2">
<view>
<text class="secondCate">/ {{item2.cat_name}} /</text>
<view class="thirdCateContainer" >
<view class="thirdCateItem" v-for="(item3,index3) in item2.children" :key="index3" @click="goToGoodList(item3)">
<image :src="item3.cat_icon" mode=""></image>
<text>{{item3.cat_name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import bus from "@/utils/bus";
export default {
data() {
return {
scrollHeight:'',
cateList:[],
currentSelectedIndex:0,
rightScrollTop:0,
leftScrollTop:0,
};
},
created(){
bus.on('resetScroll', () => {
this.currentSelectedIndex = 0
this.leftScrollTop = this.leftScrollTop ? 0 : 1
this.rightScrollTop = this.rightScrollTop === 0 ? 1 : 0
})
},
onUnload: () => {
bus.off('resetScroll')
},
onLoad() {
this.getViewUsedHeight()
this.getCateList()
console.log("哈哈哈",this.cateList);
},
methods:{
goToGoodList(item3){
console.log(item3);
uni.navigateTo({
url:'/subpkg/goods_list/goods_list?cid=' + item3.cat_id
})
},
changeSelectedIndex(index){
this.currentSelectedIndex = index
// this.secondCateList = this.cateList[index].children
this.rightScrollTop = this.rightScrollTop === 0 ? 1 : 0
},
getViewUsedHeight(){
uni.getSystemInfo({
success: (res) => {
console.log("這是獲取到的設(shè)備信息:",res);
if(res.errMsg === "getSystemInfo:ok" && res.windowHeight){
uni.$showMsg("窗口可用高度為"+res.windowHeight)
this.scrollHeight = res.windowHeight - 60
}else{
return uni.$showMsg("獲取當(dāng)前屏幕高度失敗!")
}
},fail: (err) => {
console.log("獲取屏幕高度失敗,信息為:",err);
}
})
},
async getCateList(){
const {data:res} = await uni.$http.get('/api/public/v1/categories')
console.log("這是獲取到的分類(lèi)數(shù)據(jù):",res);
if(res.meta.status !== 200) return uni.$showMsg("沒(méi)有成功獲取到分類(lèi)數(shù)據(jù)!")
this.cateList = res.message
console.log("獲取分類(lèi)的請(qǐng)求已經(jīng)結(jié)束了!!!");
// this.secondCateList = this.cateList[0].children
console.log(this.cateList);
}
}
}
</script>
在控制臺(tái)中報(bào)了這樣的錯(cuò)誤:
[Vue warn]: Error in render: “TypeError: Cannot read property ‘children’ of undefined”
TypeError: Cannot read property ‘children’ of undefined
之前第一次寫(xiě)的時(shí)候也沒(méi)問(wèn)題,就沒(méi)處理,但這次出了問(wèn)題,只好從這個(gè)提示入手。
分析過(guò)程:
1.根據(jù)提示顯然是使用v-for循環(huán)頁(yè)面渲染二級(jí)和三級(jí)分類(lèi)使用一級(jí)分類(lèi)cateList對(duì)象里面的數(shù)據(jù)即cateList[currentSelectedIndex].children 時(shí)出了問(wèn)題,但是思考了半天沒(méi)找到問(wèn)題所在,我在請(qǐng)求數(shù)據(jù)的時(shí)候就已經(jīng)將獲取到的數(shù)據(jù)賦值給了data函數(shù)中的cateList身上,currentSelectedIndex也在data函數(shù)中默認(rèn)給了定值0。
2.查閱網(wǎng)上資料說(shuō)是,頁(yè)面在第一次渲染時(shí)數(shù)據(jù)還沒(méi)有拿到造成的,使用v-if,判斷要渲染的頁(yè)面數(shù)據(jù)
是否存在,不存在時(shí)不渲染,根據(jù)提示我使用了v-if將cateList[currentSelectedIndex].children放在了class="rightScrollContainer"的scroll-view標(biāo)簽上,但是依然無(wú)效,報(bào)錯(cuò)依舊。
3.后面查閱了項(xiàng)目文檔,確實(shí)是Vue在第一次渲染頁(yè)面時(shí)拿不到數(shù)據(jù)導(dǎo)致。于是我修改了使用屬性嵌套進(jìn)行頁(yè)面渲染的方法,將cateList[currentSelectedIndex].children改為變量名secondCateList聲明在data函數(shù)中,并在onLoad函數(shù)中調(diào)用this.getCateList()方法獲取分類(lèi)數(shù)據(jù)后,將cateList[0].children的值賦值給sendCondList的變量放到頁(yè)面去渲染,但是報(bào)錯(cuò)依舊。
4.后面聯(lián)想到了Vue的聲明周期,并且根據(jù)AI的提示,我嘗試在onLoad函數(shù)中打印請(qǐng)求返回的數(shù)據(jù)this.cateList值的情況,主要源碼和運(yùn)行截圖如下:
onLoad() {
this.getViewUsedHeight()
this.getCateList()
console.log("這是onLoad函數(shù)中當(dāng)前this.cateList的值:",this.cateList);
},
async getCateList(){
const {data:res} = await uni.$http.get('/api/public/v1/categories')
console.log("這是獲取到的分類(lèi)數(shù)據(jù):",res);
if(res.meta.status !== 200) return uni.$showMsg("沒(méi)有成功獲取到分類(lèi)數(shù)據(jù)!")
this.cateList = res.message
console.log("獲取分類(lèi)的請(qǐng)求已經(jīng)結(jié)束了!!!");
}
可以看到,在onLoad函數(shù)中的請(qǐng)求方法this.getCateList()運(yùn)行結(jié)束之前,onLoad函數(shù)體中的最后一行打印語(yǔ)句就已經(jīng)執(zhí)行了,這也解釋了為什么我在請(qǐng)求函數(shù)"結(jié)束"之后修改值依然無(wú)效,頁(yè)面渲染報(bào)前面提到的錯(cuò)的原因。
解決方法:
知道了原因,我們就可以將二級(jí)分類(lèi)數(shù)據(jù)secondCateList聲明在computed之中,并且使用三元表達(dá)式判斷它的值是否存在,不存在時(shí)返回一個(gè)空數(shù)組,這樣Vue在頁(yè)面首次加載時(shí)就不會(huì)去渲染了,報(bào)錯(cuò)消失后,這個(gè)小程序頁(yè)面樣式正常,安卓樣式異常的問(wèn)題就解決了。
修改后的頁(yè)面源碼和運(yùn)行截圖如下:
<template>
<view>
<my-search ></my-search>
<view class="scrollContainer" >
<scroll-view scroll-y="true" class="leftScrollContainer" :style="{height: scrollHeight + 'px' }" :scroll-top="leftScrollTop">
<view :class="'firstCateItem ' + (index===currentSelectedIndex? 'active' :'') " v-for="(item1,index) in cateList" :key="index" @click="changeSelectedIndex(index)">
{{item1.cat_name}}
</view>
</scroll-view>
<scroll-view scroll-y="true" class="rightScrollContainer" :style="{height: scrollHeight + 'px'}" :scroll-top="rightScrollTop">
<view class="childCateContainer" v-for="(item2,index2) in secondCateList " :key="index2">
<view>
<text class="secondCate">/ {{item2.cat_name}} /</text>
<view class="thirdCateContainer" >
<view class="thirdCateItem" v-for="(item3,index3) in item2.children" :key="index3" @click="goToGoodList(item3)">
<image :src="item3.cat_icon" mode=""></image>
<text>{{item3.cat_name}}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import bus from "@/utils/bus";
export default {
data() {
return {
scrollHeight:'',
cateList:[],
currentSelectedIndex:0,
rightScrollTop:0,
leftScrollTop:0,
};
},
computed:{
secondCateList(){
//必須要設(shè)置一個(gè)空數(shù)組,在第一次渲染的時(shí)候,this.cateList是沒(méi)有的,再調(diào)用它的子屬性children會(huì)報(bào)錯(cuò),雖然小程序不影響結(jié)果,但是安卓上會(huì)導(dǎo)致頁(yè)面樣式渲染出現(xiàn)異常
return this.cateList[this.currentSelectedIndex] ? this.cateList[this.currentSelectedIndex].children : []
}
},
created(){
bus.on('resetScroll', () => {
this.currentSelectedIndex = 0
this.leftScrollTop = this.leftScrollTop ? 0 : 1
this.rightScrollTop = this.rightScrollTop === 0 ? 1 : 0
})
},
onUnload: () => {
bus.off('resetScroll')
},
onLoad() {
this.getViewUsedHeight()
this.getCateList()
console.log("這是onLoad函數(shù)中當(dāng)前this.cateList的值:",this.cateList);
},
methods:{
goToGoodList(item3){
console.log(item3);
uni.navigateTo({
url:'/subpkg/goods_list/goods_list?cid=' + item3.cat_id
})
},
changeSelectedIndex(index){
this.currentSelectedIndex = index
// this.secondCateList = this.cateList[index].children
this.rightScrollTop = this.rightScrollTop === 0 ? 1 : 0
},
getViewUsedHeight(){
uni.getSystemInfo({
success: (res) => {
console.log("這是獲取到的設(shè)備信息:",res);
if(res.errMsg === "getSystemInfo:ok" && res.windowHeight){
uni.$showMsg("窗口可用高度為"+res.windowHeight)
this.scrollHeight = res.windowHeight - 60
}else{
return uni.$showMsg("獲取當(dāng)前屏幕高度失敗!")
}
},fail: (err) => {
console.log("獲取屏幕高度失敗,信息為:",err);
}
})
},
async getCateList(){
const {data:res} = await uni.$http.get('/api/public/v1/categories')
console.log("這是獲取到的分類(lèi)數(shù)據(jù):",res);
if(res.meta.status !== 200) return uni.$showMsg("沒(méi)有成功獲取到分類(lèi)數(shù)據(jù)!")
this.cateList = res.message
console.log("獲取分類(lèi)的請(qǐng)求已經(jīng)結(jié)束了!!!");
}
}
}
</script>
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-847297.html
總結(jié)
剛學(xué)完uni-app時(shí),看到有人說(shuō)這個(gè)框架就是一端運(yùn)行多端報(bào)錯(cuò)還有點(diǎn)懷疑,這下不得不信了。不過(guò)也有原因在于我當(dāng)時(shí)沒(méi)有去處理復(fù)雜對(duì)象中的嵌套數(shù)據(jù)在頁(yè)面渲染錯(cuò)誤所導(dǎo)致的,同時(shí)也重新認(rèn)識(shí)了下onLoad函數(shù)體語(yǔ)句和異步請(qǐng)求方法的執(zhí)行順序問(wèn)題。總而言之,在使用接口返回的復(fù)雜數(shù)據(jù)渲染頁(yè)面時(shí),優(yōu)先使用computed計(jì)算屬性,結(jié)合三元表達(dá)式去判斷要渲染的數(shù)據(jù)源是否已經(jīng)存在,不存在應(yīng)給定空數(shù)組或?qū)ο?/strong>,以避免一端運(yùn)行,多端報(bào)錯(cuò)的可能。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-847297.html
到了這里,關(guān)于uni-app框架 微信小程序頁(yè)面顯示正常,但安卓頁(yè)面樣式顯示異常的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!