123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- <template>
- <uv-popup ref="popup" mode="top" :safe-area-inset-bottom="false" :offset-top="relTop" @change="handleChange">
- <scroll-view scroll-y style="max-height: 35vh;">
- <view class="w-screen px-30 py-10 box-border" @touchmove.stop>
- <component :is="comp" v-model="model[config.key]" placement="column" icon-placement="right">
- <component :is="itemComp" v-for="i in list" :name="getValue(i)" :label="getLabel(i)"/>
- </component>
- </view>
- </scroll-view>
- <mx-bottom-buttons left-type="primary" left="重置" :right="right" class="p-30"
- @left="handleReset" @right="handleConfirm"/>
- </uv-popup>
- </template>
- <script setup>
- import {ref, computed} from 'vue';
- import {useElementBounding} from "@vueuse/core";
- import {useInjectConditionDropdownPopup} from "@/components/mx-condition-dropdown/useConditionDropdownPopupInjection";
- import {deepClone, sleep} from "@/uni_modules/uv-ui-tools/libs/function";
- import {useInjectSearchModel} from "@/components/mx-condition/useSearchModelInjection";
- import UvCheckboxGroup from "@/uni_modules/uv-checkbox/components/uv-checkbox-group/uv-checkbox-group.vue";
- import UvRadioGroup from "@/uni_modules/uv-radio/components/uv-radio-group/uv-radio-group.vue";
- import UvCheckbox from "@/uni_modules/uv-checkbox/components/uv-checkbox/uv-checkbox.vue";
- import UvRadio from "@/uni_modules/uv-radio/components/uv-radio/uv-radio.vue";
- import {func} from "@/uni_modules/uv-ui-tools/libs/function/test";
- const popup = ref(null)
- const {bottom, container} = useInjectConditionDropdownPopup()
- const {queryParams} = useInjectSearchModel()
- const model = ref({}) // 存放queryParams副本
- const show = ref(false)
- const condition = ref(null)
- const list = computed(() => condition.value?.list || [])
- const config = computed(() => condition.value?.config || {})
- const multiple = computed(() => config.value?.multiple)
- const comp = computed(() => multiple.value ? UvCheckboxGroup : UvRadioGroup)
- const itemComp = computed(() => multiple.value ? UvCheckbox : UvRadio)
- const right = computed(() => {
- if (!multiple.value) return '确定'
- const cur = model.value[config.value.key]
- if (cur.length < 1) return '确定'
- return `确定(${cur.length})`
- })
- // TODO: 相对位置不精准
- // baseTop 理论上应该找当前容器的值,但目前筛选器是紧贴swiper容器的,所以取的是筛选器的顶部
- // 如果以后有定位不对的情况,请修正该值
- const {top: baseTop} = useElementBounding(container)
- const {bottom: baseBottom} = useElementBounding(bottom)
- const relTop = computed(() => baseBottom.value - baseTop.value - 1)
- const handleReset = () => {
- // 重置本地model状态
- if (multiple.value) model.value[config.value.key] = []
- else model.value[config.value.key] = ''
- if (config.value.defaultValue) {
- let val = config.value.defaultValue
- if (func(val)) val = val(condition.value)
- model.value[config.value.key] = val
- }
- }
- const handleConfirm = () => {
- // 将本地model状态赋值回queryParams
- const key = config.value.key
- queryParams.value[key] = model.value[key]
- close()
- }
- const open = function (cond) {
- // console.log('open begin', new Date().getTime())
- if (cond == condition.value && show.value) {
- popup.value.close()
- // console.log('open end', new Date().getTime())
- } else {
- condition.value = cond
- // 每次打开都创建一个副本,用户确认后才将结果反向从model赋回queryParams
- model.value = deepClone(queryParams.value)
- popup.value.open()
- // console.log('open end', new Date().getTime())
- }
- }
- const close = function () {
- // console.log('close begin', new Date().getTime())
- popup.value.close()
- // console.log('close end', new Date().getTime())
- }
- const handleChange = async function (e) {
- // console.log('change begin', new Date().getTime())
- show.value = e.show
- await sleep()
- if (!show.value) {
- // always clean current condition&model while hidden.
- condition.value = null
- model.value = {}
- }
- // console.log('change end', new Date().getTime())
- }
- const getLabel = (item) => config.value.keyName ? item[config.value.keyName] : item
- const getValue = (item) => config.value.keyValue ? item[config.value.keyValue] : item
- defineExpose({open, close, show, condition})
- </script>
- <style scoped lang="scss">
- ::v-deep(.uv-checkbox-group),
- ::v-deep(.uv-radio-group) {
- .uv-checkbox-label--right,
- .uv-radio-label--right {
- padding-top: 20rpx;
- padding-bottom: 20rpx;
- border-bottom: 0.5px solid var(--border-color);
- }
- }
- </style>
|