uni-app 循环出来的picker-view-column 定位不会滚动到对应位置

发布于 1周前 作者 yibo5220 来自 Uni-App

uni-app 循环出来的picker-view-column 定位不会滚动到对应位置

问题描述

循环出来的picker-view-column 手动改picker-view 的value不生效

<picker-view :style="pickerViewStyle" :indicator-style="indicatorStyle" :immediateChange="immediateChange"  
    :value="pickerState.innerIndex" @change="changeHandler">  
    <picker-view-column v-for="(item,mainIdx) in timeState.columnList" :key="item.type">  
        <view v-for="(time,idx) in item.values" :key="`${item.type}--${time}-${idx}`" class="text-center">  
            <text :style="{height: $uv.addUnit(props.itemHeight),  lineHeight: $uv.addUnit(props.itemHeight),   
            fontWeight: idx === pickerState.innerIndex[mainIdx] ? 'bold' : 'normal'}">  
                {{time}}  
            </text>  
        </view>  
    </picker-view-column>  
</picker-view>
function init() {  
    getOriginColumns()  
}  

function times(n, iteratee) {  
    let index = -1  
    const result = Array(n < 0 ? 0 : n)  
    while (++index < n) {  
        result[index] = iteratee(index)  
    }  
    return result  
}  

function getOriginColumns() {  
    // 生成各列的值  
    const results = getRanges().map(({ type, range }) => {  
        let values = times(range[1] - range[0] + 1, (index) => {  
            let value = range[0] + index  
            value = type === 'year' ? `${value}` : uni.$uv.padZero(value)  
            return value  
        })  
        timeState[type] = values  
        return { type, values }  
    })  
    timeState.columnList = results  
    console.log('getOriginColumns', results);  
    nextTick(() => {  
        uni.$uv.sleep(100).then(res => {  
            pickerState.innerIndex = uni.$uv.deepClone([10, 10, 6, 5, 0])  
        })  
    })  
}  

// 获取每列的最大和最小值  
function getRanges() {  
    if (props.mode === 'time') {  
        return [{  
            type: 'hour',  
            range: [props.minHour, props.maxHour],  
        }, {  
            type: 'minute',  
            range: [props.minMinute, props.maxMinute],  
        }, ];  
    }  
    const { maxYear, maxDate, maxMonth, maxHour, maxMinute, } = getBoundary('max', '');  
    const { minYear, minDate, minMonth, minHour, minMinute, } = getBoundary('min', '');  
    const result = [{  
        type: 'year',  
        range: [minYear, maxYear],  
    }, {  
        type: 'month',  
        range: [minMonth, maxMonth],  
    }, {  
        type: 'day',  
        range: [minDate, maxDate],  
    }, {  
        type: 'hour',  
        range: [minHour, maxHour],  
    }, {  
        type: 'minute',  
        range: [minMinute, maxMinute],  
    }, ];  
    if (props.mode === 'date') result.splice(3, 2);  
    if (props.mode === 'year-month') result.splice(2, 3);  
    if (props.mode === 'year') result.splice(1, 4);  
    return result;  
}  

function getBoundary(type, innerValue) {  
    const value = new Date()  
    const boundary = new Date(props[`${type}Date`])  
    const year = dayjs(boundary).year()  
    let month = 1  
    let date = 1  
    let hour = 0  
    let minute = 0  
    if (type === 'max') {  
        month = 12  
        // 月份的天数  
        date = dayjs(value).daysInMonth()  
        hour = 23  
        minute = 59  
    }  
    // 获取边界值,逻辑是:当年达到了边界值(最大或最小年),就检查月允许的最大和最小值,以此类推  
    if (dayjs(value).year() === year) {  
        month = dayjs(boundary).month() + 1  
        if (dayjs(value).month() + 1 === month) {  
            date = dayjs(boundary).date()  
            if (dayjs(value).date() === date) {  
                hour = dayjs(boundary).hour()  
                if (dayjs(value).hour() === hour) {  
                    minute = dayjs(boundary).minute()  
                }  
            }  
        }  
    }  
    return {  
        [`${type}Year`]: year,  
        [`${type}Month`]: month,  
        [`${type}Date`]: date,  
        [`${type}Hour`]: hour,  
        [`${type}Minute`]: minute  
    }  
}  

onMounted(() => {  
    init()  
})

1 回复

uni-app 中使用 picker-viewpicker-view-column 时,如果循环生成的内容需要定位到特定的位置,你需要确保 picker-viewvalue 属性正确设置,并且 picker-view-column 的数据也正确无误。以下是一个示例代码,展示了如何实现这一功能。

示例代码

假设你有一个列表数据,并希望使用 picker-view 来选择列表中的项。

<template>
  <view>
    <button @click="scrollToIndex(selectedIndex)">Scroll to Index {{ selectedIndex }}</button>
    <picker-view :value="pickerValue" @change="onPickerChange">
      <picker-view-column v-for="(item, index) in items" :key="index">
        <view v-for="(subItem, subIndex) in item" :key="subIndex">{{ subItem }}</view>
      </picker-view-column>
    </picker-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      items: [
        ['Item 1-1', 'Item 1-2', 'Item 1-3'],
        ['Item 2-1', 'Item 2-2', 'Item 2-3'],
        ['Item 3-1', 'Item 3-2', 'Item 3-3']
      ],
      pickerValue: [0, 0], // 初始值,表示第一个picker-view-column的第一个item
      selectedIndex: 0 // 当前选中的索引,用于演示滚动到指定位置
    };
  },
  methods: {
    scrollToIndex(index) {
      // 更新pickerValue以滚动到指定的位置
      // 假设我们滚动到第2个picker-view-column的第2个item
      const columnIndex = Math.floor(index / this.items[0].length); // 计算列索引
      const rowIndex = index % this.items[0].length; // 计算行索引
      this.pickerValue = [columnIndex, rowIndex];
    },
    onPickerChange(e) {
      this.pickerValue = e.detail.value;
      // 你可以在这里处理选择变化后的逻辑
    }
  }
};
</script>

<style>
/* 添加一些样式以便更好地查看效果 */
button {
  margin: 20px;
}
picker-view {
  width: 100%;
  height: 300px;
}
</style>

解释

  1. 数据绑定items 是一个二维数组,每个子数组代表一个 picker-view-column 的选项。
  2. pickerValue:这是一个数组,用于存储当前选中的列和行的索引。初始值 [0, 0] 表示第一个列的第一个项。
  3. scrollToIndex 方法:根据传入的 index 计算对应的列和行索引,并更新 pickerValue,从而滚动到指定的位置。
  4. 事件处理onPickerChange 方法用于处理 picker-view 的值变化事件。

通过这种方式,你可以确保循环生成的 picker-view-column 能够正确地滚动到指定的位置。

回到顶部