<!--
|
通用表单选择项
|
放在 u-form-item 里使用,替代各页面手写的「只读 u-input + up-action-sheet/up-datetime-picker」组合。
|
|
下拉:
|
<u-form-item label="所属项目" prop="projectId" required border-bottom>
|
<FormPicker v-model="form.projectId" :display-text="form.projectName"
|
type="select" title="选择项目" :options="projectOptions"
|
@change="onProjectChange" />
|
</u-form-item>
|
|
日期:
|
<u-form-item label="立案时间" prop="filingDate" required border-bottom>
|
<FormPicker v-model="form.filingDate" type="date" placeholder="请选择立案时间" />
|
</u-form-item>
|
|
options 支持三种写法,取值优先级:
|
显示文本 item.name → item.text → item.label → item.displayText
|
实际值 item.value → item.id → item.code
|
也可以用 label-key / value-key 显式指定。
|
-->
|
<template>
|
<view class="form-picker">
|
<u-input :modelValue="text"
|
:placeholder="placeholder"
|
:disabled="disabled"
|
:readonly="true"
|
:clearable="clearable && !disabled && !readonly"
|
@click="open"
|
@update:modelValue="onInputUpdate">
|
<template #suffix>
|
<u-icon v-if="!disabled && !readonly"
|
name="arrow-right"
|
color="#c0c4cc"
|
@click="open"></u-icon>
|
</template>
|
</u-input>
|
|
<up-action-sheet v-if="type === 'select'"
|
:show="showSheet"
|
:actions="actions"
|
:title="title"
|
@select="onSelect"
|
@close="showSheet = false"></up-action-sheet>
|
|
<up-datetime-picker v-if="type === 'date'"
|
:show="showPicker"
|
v-model="pickerValue"
|
:mode="dateMode"
|
@confirm="onDateConfirm"
|
@cancel="showPicker = false"></up-datetime-picker>
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, ref } from "vue";
|
import { formatDateToYMD } from "@/utils/ruoyi";
|
import { parseDate } from "@/utils/warning";
|
|
const props = defineProps({
|
modelValue: {
|
type: [String, Number, Boolean, null],
|
default: "",
|
},
|
// select 下拉 | date 日期
|
type: {
|
type: String,
|
default: "select",
|
},
|
// 直接指定显示文本;不传则按 options 反查
|
displayText: {
|
type: String,
|
default: "",
|
},
|
options: {
|
type: Array,
|
default: () => [],
|
},
|
title: {
|
type: String,
|
default: "",
|
},
|
placeholder: {
|
type: String,
|
default: "请选择",
|
},
|
labelKey: {
|
type: String,
|
default: "",
|
},
|
valueKey: {
|
type: String,
|
default: "",
|
},
|
// 日期精度:date | datetime | time | year-month
|
dateMode: {
|
type: String,
|
default: "date",
|
},
|
disabled: {
|
type: Boolean,
|
default: false,
|
},
|
readonly: {
|
type: Boolean,
|
default: false,
|
},
|
clearable: {
|
type: Boolean,
|
default: true,
|
},
|
});
|
|
const emit = defineEmits(["update:modelValue", "change"]);
|
|
const showSheet = ref(false);
|
const showPicker = ref(false);
|
const pickerValue = ref(Date.now());
|
|
const optionValue = item =>
|
props.valueKey
|
? item?.[props.valueKey]
|
: (item?.value ?? item?.id ?? item?.code);
|
|
const optionLabel = item =>
|
props.labelKey
|
? item?.[props.labelKey]
|
: (item?.name ?? item?.text ?? item?.label ?? item?.displayText ?? "");
|
|
const actions = computed(() =>
|
(props.options || []).map(item => ({
|
text: String(optionLabel(item) ?? ""),
|
value: optionValue(item),
|
data: item,
|
}))
|
);
|
|
const text = computed(() => {
|
if (props.displayText) return props.displayText;
|
if (props.modelValue === undefined || props.modelValue === null) return "";
|
if (props.type === "date") return String(props.modelValue);
|
const matched = (props.options || []).find(
|
item => String(optionValue(item)) === String(props.modelValue)
|
);
|
return matched ? String(optionLabel(matched)) : "";
|
});
|
|
const open = () => {
|
if (props.disabled || props.readonly) return;
|
if (props.type === "select") {
|
showSheet.value = true;
|
return;
|
}
|
const base = parseDate(props.modelValue);
|
pickerValue.value = base ? base.getTime() : Date.now();
|
showPicker.value = true;
|
};
|
|
// 用户点击 u-input 的清除按钮时,把空值同步出去
|
const onInputUpdate = value => {
|
if (value !== "" && value !== undefined) return;
|
emit("update:modelValue", "");
|
emit("change", "", null);
|
};
|
|
const onSelect = item => {
|
showSheet.value = false;
|
emit("update:modelValue", item.value);
|
emit("change", item.value, item.data);
|
};
|
|
const onDateConfirm = e => {
|
showPicker.value = false;
|
const value = formatDateToYMD(e.value);
|
emit("update:modelValue", value);
|
emit("change", value, null);
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.form-picker {
|
width: 100%;
|
}
|
</style>
|