| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- <template>
- <div class="app-select">
- <Field ref="fieldRef" :name="name" :rules="rules" @click="showPicker = true" :is-link="isLink">
- <template #label>
- <slot name="label">
- {{ label }}
- </slot>
- </template>
- <template #input>
- <slot name="input">
- <input :value="columnLabel" :placeholder="placeholder" readonly />
- </slot>
- </template>
- </Field>
- <Popup v-model:show="showPicker" position="bottom" teleport="body">
- <Picker :columns="columns" @cancel="onCancel" @confirm="onConfirm" />
- </Popup>
- </div>
- </template>
- <script lang="ts" setup>
- import { shallowRef, computed, PropType } from 'vue'
- import { Field, FieldRule, Popup, Picker, PickerOption, FieldInstance } from 'vant'
- const props = defineProps({
- modelValue: {
- type: [Number, String]
- },
- options: {
- type: Array,
- default: () => ([])
- },
- optionProps: {
- type: Object as PropType<{ label?: string; value?: string; }>,
- default: () => ({
- label: 'label',
- value: 'value'
- })
- },
- rules: {
- type: Array as PropType<FieldRule[]>
- },
- name: String,
- label: String,
- placeholder: {
- type: String,
- default: '请选择'
- },
- isLink: {
- type: Boolean,
- default: true
- }
- })
- const emit = defineEmits(['update:show', 'update:modelValue', 'confirm', 'cancel'])
- const fieldRef = shallowRef<FieldInstance>()
- const showPicker = shallowRef(false) // 是否弹出选择器
- const selectedIndex = shallowRef(-1)
- const columns = computed(() => {
- if (props.options) {
- return props.options.map((e) => e[props.optionProps.label])
- }
- return []
- })
- // 当前显示的标签
- const columnLabel = computed(() => {
- const item = props.options[selectedIndex.value]
- if (item) {
- return item[props.optionProps.label] ?? ''
- }
- return ''
- })
- // 更新当前选中的值
- const updateValue = (index: number) => {
- const item = props.options[index]
- const value = item[props.optionProps.value]
- selectedIndex.value = index
- fieldRef.value?.validate()
- emit('update:modelValue', value)
- }
- const onCancel = (currentValue: PickerOption, currentIndex: number) => {
- showPicker.value = false
- emit('cancel', currentValue, currentIndex)
- }
- const onConfirm = (currentValue: PickerOption, currentIndex: number) => {
- showPicker.value = false
- updateValue(currentIndex)
- emit('confirm', currentValue, currentIndex)
- }
- </script>
- <style lang="less" scoped>
- @import './index.less';
- </style>
|