uni-app picker mode=selector时,range=[]为空数组会控制台报错且页面无法渲染

uni-app picker mode=selector时,range=[]为空数组会控制台报错且页面无法渲染

开发环境信息

项目 信息
产品分类 uniapp/App
PC操作系统 Windows
操作系统版本 window10家庭中文版
HBuilderX 正式
HBuilderX版本 3.1.14
手机系统 Android
手机系统版本 Android 11
手机厂商 华为
手机机型 NLS-MT66
页面类型 vue
打包方式 云端
项目创建方式 HBuilderX

示例代码:

<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-title uni-common-pl">普通选择器</view>
<view class="uni-list">
<view class="uni-list-cell">
<view class="uni-list-cell-left">
当前选择
</view>
<view class="uni-list-cell-db">
<picker @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input">{{array[index].name}}</view>
</picker>
</view>
</view>
</view>  
<!-- #ifndef MP-ALIPAY -->  
<view class="uni-title uni-common-pl">多列选择器</view>  
<view class="uni-list">  
    <view class="uni-list-cell">  
        <view class="uni-list-cell-left">  
            当前选择  
        </view>  
        <view class="uni-list-cell-db">  
            <picker mode="multiSelector" @columnchange="bindMultiPickerColumnChange" :value="multiIndex" :range="multiArray">  
                <view class="uni-input">{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}</view>  
            </picker>  
        </view>  
    </view>  
</view>  
<!-- #endif -->  

<view class="uni-title uni-common-pl">时间选择器</view>  
<view class="uni-list">  
    <view class="uni-list-cell">  
        <view class="uni-list-cell-left">  
            当前选择  
        </view>  
        <view class="uni-list-cell-db">  
            <picker mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange">  
                <view class="uni-input">{{time}}</view>  
            </picker>  
        </view>  
    </view>  
</view>  
<view class="uni-picker-tips">  
    注:选择 09:01 ~ 21:01 之间的时间, 不在区间内不能选中  
</view>  

<view class="uni-title uni-common-pl">日期选择器</view>  
<view class="uni-list">  
    <view class="uni-list-cell">  
        <view class="uni-list-cell-left">  
            当前选择  
        </view>  
        <view class="uni-list-cell-db">  
            <picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">  
                <view class="uni-input">{{date}}</view>  
            </picker>  
        </view>  
    </view>  
</view>  
<view class="uni-picker-tips">  
    注:选择当前时间 ±10 年之间的时间, 不在区间内不能选中  
</view>  
</view>  
</template>  
<script>  
function getDate(type) {  
    const date = new Date();  

    let year = date.getFullYear();  
    let month = date.getMonth() + 1;  
    let day = date.getDate();  

    if (type === 'start') {  
        year = year - 10;  
    } else if (type === 'end') {  
        year = year + 10;  
    }  
    month = month > 9 ? month : '0' + month;;  
    day = day > 9 ? day : '0' + day;  

    return `${year}-${month}-${day}`;  
}  
export default {  
    data() {  
        return {  
            title: 'picker',  
            array: [], // 将第一个picker的range设置为空数组,会直接导致页面渲染不出来,并报错,该示例为官网demo页面修改  
            index: 0,  
            multiArray: [  
                ['亚洲', '欧洲'],  
                ['中国', '日本'],  
                ['北京', '上海', '广州']  
            ],  
            multiIndex: [0, 0, 0],  
            date: getDate({  
                format: true  
            }),  
            startDate:getDate('start'),  
            endDate:getDate('end'),  
            time: '12:01'  
        }  
    },  
    methods: {  
        bindPickerChange: function(e) {  
            console.log('picker发送选择改变,携带值为:' + e.detail.value)  
            this.index = e.detail.value  
        },  
        bindMultiPickerColumnChange: function(e) {  
            console.log('修改的列为:' + e.detail.column + ',值为:' + e.detail.value)  
            this.multiIndex[e.detail.column] = e.detail.value  
            switch (e.detail.column) {  
                case 0: //拖动第1列  
                    switch (this.multiIndex[0]) {  
                        case 0:  
                            this.multiArray[1] = ['中国', '日本']  
                            this.multiArray[2] = ['北京', '上海', '广州']  
                            break  
                        case 1:  
                            this.multiArray[1] = ['英国', '法国']  
                            this.multiArray[2] = ['伦敦', '曼彻斯特']  
                            break  
                    }  
                    this.multiIndex.splice(1, 1, 0)  
                    this.multiIndex.splice(2, 1, 0)  
                    break  
                case 1: //拖动第2列  
                    switch (this.multiIndex[0]) { //判断第一列是什么  
                        case 0:  
                            switch (this.multiIndex[1]) {  
                                case 0:  
                                    this.multiArray[2] = ['北京', '上海', '广州']  
                                    break  
                                case 1:  
                                    this.multiArray[2] = ['东京','北海道']  
                                    break  
                            }  
                            break  
                        case 1:  
                            switch (this.multiIndex[1]) {  
                                case 0:  
                                    this.multiArray[2] = ['伦敦', '曼彻斯特']  
                                    break  
                                case 1:  
                                    this.multiArray[2] = ['巴黎', '马赛']  
                                    break  
                            }  
                            break  
                    }  
                    this.multiIndex.splice(2, 1, 0)  
                    break  
            }  
            this.$forceUpdate()  
        },  
        bindDateChange: function(e) {  
            this.date = e.detail.value  
        },  
        bindTimeChange: function(e) {  
            this.time = e.detail.value  
        }  

    }  
}  
</script>  
<style>  
.uni-picker-tips {  
font-size: 12px;  
color: #666;  
margin-bottom: 15px;  
padding: 0 15px;  
/* text-align: right; */  
}  
</style>  

操作步骤:

本地使用HBuilder新建一个uniapp项目,选择hell uniapp模板直接生成。将pages/component/picker/picker.vue里面的array设置为[]空数组,运行到浏览器打开,进入表单组件—picker演示页面会发现页面全部无法渲染出来。

预期结果:

进入表单组件—picker演示页面会发现页面全部无法渲染出来。

实际结果:

进入表单组件—picker演示页面会发现页面全部无法渲染出来。

bug描述:

uniapp picker mode = selector的时候,range = []为空数组的时候会控制台报错,并导致页面直接渲染不出来,使用的示例为官网hello uniapp模板示例。


更多关于uni-app picker mode=selector时,range=[]为空数组会控制台报错且页面无法渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app picker mode=selector时,range=[]为空数组会控制台报错且页面无法渲染的实战教程也可以访问 https://www.itying.com/category-93-b0.html


picker组件的range属性设置为空数组时,确实会导致页面渲染失败和控制台报错。这是因为在模板中使用了{{array[index].name}}这样的表达式,当array为空数组时,array[0]undefined,访问undefined.name就会抛出错误。

这是一个典型的数据边界处理问题。当range为空数组时,index的值(默认为0)会超出数组的有效索引范围。

解决方案:

  1. 添加空值检查
<view class="uni-input">{{array[index] ? array[index].name : '请选择'}}</view>
  1. 设置默认值
data() {
    return {
        array: [], // 初始为空数组
        index: 0
    }
}
  1. 在数据加载完成后设置默认选项: 如果数据是异步获取的,确保在数据加载完成后再设置默认选中项:
// 模拟异步数据加载
setTimeout(() => {
    this.array = [{name: '选项1'}, {name: '选项2'}];
    this.index = 0; // 重置为有效索引
}, 1000);
  1. 使用计算属性
computed: {
    displayValue() {
        return this.array[this.index] ? this.array[this.index].name : '请选择';
    }
}

然后在模板中使用:

<view class="uni-input">{{displayValue}}</view>
回到顶部