diff --git a/src/components/CommonPicker/index.vue b/src/components/CommonPicker/index.vue index 82dd2a0..b386d33 100644 --- a/src/components/CommonPicker/index.vue +++ b/src/components/CommonPicker/index.vue @@ -10,6 +10,7 @@ ref="pickerRef" :show="showPicker" :columns="columns" + :defaultIndex="defaultIndex" closeOnClickOverlay @cancel="handleCancel" @confirm="handleConfirm" @@ -94,7 +95,7 @@ const displayValue = computed(() => { } // 如果是字符串数组 - if (typeof props.options[0] === 'string') { + if (props.options.length > 0 && typeof props.options[0] === 'string') { return props.options.find((item) => item === props.modelValue) || '' } @@ -103,6 +104,29 @@ const displayValue = computed(() => { return option ? option[props.labelKey] : '' }) +/** + * 计算默认选中索引 + * 业务背景:当选择器打开时,需要根据当前 modelValue 找到对应的选项索引,以便选择器默认选中该项 + * 设计决策:通过遍历 options 数组,找到与 modelValue 匹配的选项索引 + */ +const defaultIndex = computed(() => { + if (!props.modelValue || props.options.length === 0) { + return [0] + } + + // 如果是字符串数组 + if (typeof props.options[0] === 'string') { + const index = props.options.findIndex((item) => item === props.modelValue) + return [index >= 0 ? index : 0] + } + + // 如果是对象数组 + const index = props.options.findIndex( + (item) => String(item[props.valueKey]) === String(props.modelValue), + ) + return [index >= 0 ? index : 0] +}) + /** * 打开选择器 */ @@ -119,12 +143,32 @@ const handleCancel = () => { /** * 确认选择 - * @param {Object} e - 事件对象 + * 业务背景:处理用户确认选择的操作,获取选中的值并触发更新 + * 设计决策: + * 1. up-picker 的 confirm 事件返回的 e.value[0] 是一个对象,包含 text 和 value 属性 + * 2. update:modelValue 传递值,符合 v-model 标准 + * 3. change 事件传递整个项对象(包含 label 和 value),方便父组件使用 + * @param {Object} e - 事件对象,e.value[0] 包含 { text, value } */ const handleConfirm = (e) => { - const selectedValue = e.value[0] + // up-picker 返回的 e.value[0] 是一个对象,包含 text 和 value + const selectedItem = e.value[0] + const selectedValue = selectedItem?.value ?? selectedItem + + // 从原始 options 中找到对应的项对象,以便传递完整的 label 和 value + let changeItem = null + if (props.options.length > 0) { + if (typeof props.options[0] === 'string') { + changeItem = { label: selectedItem?.text, value: selectedValue } + } else { + changeItem = props.options.find( + (item) => String(item[props.valueKey]) === String(selectedValue), + ) || { label: selectedItem?.text, value: selectedValue } + } + } + emit('update:modelValue', selectedValue) - emit('change', selectedValue) + emit('change', changeItem || { label: selectedItem?.text, value: selectedValue }) showPicker.value = false } diff --git a/src/components/DatePicker/index.vue b/src/components/DatePicker/index.vue index a156cf4..ac0ce7b 100644 --- a/src/components/DatePicker/index.vue +++ b/src/components/DatePicker/index.vue @@ -11,8 +11,8 @@ ref="datePickerRef" :mode="pickerMode" :show="showPicker" - :minDate="minDate" - :maxDate="maxDate" + :minDate="computedMinDate" + :maxDate="computedMaxDate" v-model="pickerValue" @cancel="handleCancel" @confirm="handleConfirm" @@ -20,7 +20,7 @@