ykt-team-wxapp/components/form-template/form-cell/form-mult-select-and-other.vue

140 lines
3.9 KiB
Vue
Raw Permalink Normal View History

2026-02-09 15:17:45 +08:00
<template>
<common-cell :name="name" :required="required">
<view class="form-content__wrapper" @click="showPopup()">
<view class="w-0 flex-grow leading-normal text-base line-clamp-2">
{{ valueStr || '' }}
</view>
<!-- <view class="flex-main-content truncate" :class="value ? '' : 'form__placeholder'">
{{ valueStr || '' }}
</view> -->
<uni-icons class="form-arrow" type="arrowright"></uni-icons>
</view>
</common-cell>
<view v-if="show" class="teleport-container">
<uni-popup ref="popup" type="center" :mask-click="false">
<view class="bg-white rounded overflow-hidden" style="width: 690rpx;">
<view class="flex items-center justify-between px-15 py-12 border-b">
<view class="text-lg font-semibold text-dark">请选择</view>
<uni-icons type="closeempty" :size="24" color="#999" @click="close"></uni-icons>
</view>
<scroll-view scroll-y="true" class="popup-content-scroll">
<view class="px-15 py-12">
<view class="flex flex-wrap">
<view v-for="(i, idx) in range" :key="idx" class="mt-10 mr-5 px-10 py-5 text-base rounded-sm"
:class="selectMap[idx] ? 'bg-primary border-primary text-white' : 'border'" @click="toggle(i)">
{{ i }}
</view>
</view>
<view v-if="hasOther" class="mt-10 px-10 py-5 border rounded-sm">
<input v-model="otherText" class="text-base" placeholder-class="text-base" @input="changeOther($event)" />
</view>
<view class="w-full pt-15"></view>
</view>
</scroll-view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { computed, ref } from 'vue';
import useDebounce from '@/utils/useDebounce';
import commonCell from '../common-cell.vue';
const emits = defineEmits(['change']);
const props = defineProps({
form: {
type: Object,
default: () => ({})
},
name: {
default: ''
},
range: {
type: Array,
default: () => []
},
required: {
type: Boolean,
default: false
},
disableChange: {
type: Boolean,
default: false
},
title: {
default: ''
}
})
const popup = ref(null);
const show = ref(false);
const otherText = ref('');
const value = computed(() => props.form && Array.isArray(props.form[props.title]) ? props.form[props.title] : [])
const valueStr = computed(() => value.value.filter(i => i !== '其他').join(','));
const hasOther = computed(() => value.value.includes('其他'));
const hasNo = computed(() => value.value.includes('无'));
const selectMap = computed(() => (props.range || []).map(i => value.value.includes(i)))
const changeOther = useDebounce(() => {
let val = value.value.filter(i => (props.range || []).includes(i));
if (otherText.value) {
val.push(otherText.value);
}
emits('change', {
title: props.title,
value: val
})
})
function close() {
popup.value?.close();
show.value = false;
}
function showPopup() {
if (props.disableChange) return;
show.value = true;
const others = value.value.filter(i => !props.range.includes(i));
otherText.value = others.length ? others.join(',') : '';
setTimeout(() => {
popup.value?.open();
}, 750)
}
function toggle(i) {
let val = [...value.value];
if (i === '无') {
val = hasNo.value ? [] : ['无'];
} else if (i === '其他') {
if (hasOther.value) {
val = val.filter(v => v !== '其他');
otherText.value = '';
} else {
val = val.filter(v => v !== '无');
val.push('其他');
otherText.value = '';
}
} else if (val.includes(i)) {
val = val.filter(v => v !== i);
} else {
val = val.filter(v => v !== '无');
val.push(i);
}
emits('change', {
title: props.title,
value: val
})
console.log(value.value);
}
</script>
<style>
@import '../cell-style.css';
.popup-content-scroll {
max-height: 65vh;
}
</style>