133 lines
3.1 KiB
Vue
133 lines
3.1 KiB
Vue
|
<template>
|
||
|
<view class="property-list">
|
||
|
<uni-popup type="bottom" ref="propertyListPopupRef" background-color="#fff">
|
||
|
<view class="popup-header">
|
||
|
<view class="button-cancel" @click="onClosePopup">取消</view>
|
||
|
<view class="button-link" @click="onConfirmPopup">确定</view>
|
||
|
</view>
|
||
|
<view class="popup-content">
|
||
|
<view
|
||
|
v-for="item in propertyList"
|
||
|
:key="item.id"
|
||
|
:class="['property-item', item.checked ? 'active' : '']"
|
||
|
@tap="chooseProperty(item)"
|
||
|
>
|
||
|
{{ item.label }}
|
||
|
</view>
|
||
|
</view>
|
||
|
</uni-popup>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script setup>
|
||
|
import { ref, computed, defineEmits, defineProps, defineExpose } from 'vue'
|
||
|
|
||
|
/**
|
||
|
* todo 底部高度配置
|
||
|
*/
|
||
|
|
||
|
const props = defineProps({
|
||
|
modelValue: {
|
||
|
default: () => [],
|
||
|
required: true,
|
||
|
type: Array,
|
||
|
},
|
||
|
})
|
||
|
|
||
|
const emit = defineEmits(['update:modelValue'])
|
||
|
|
||
|
const propertyList = ref([
|
||
|
{
|
||
|
label: '红色',
|
||
|
id: 1,
|
||
|
checked: false,
|
||
|
},
|
||
|
{
|
||
|
label: '蓝色',
|
||
|
id: 2,
|
||
|
checked: false,
|
||
|
},
|
||
|
{
|
||
|
label: '白色',
|
||
|
id: 3,
|
||
|
checked: false,
|
||
|
},
|
||
|
])
|
||
|
|
||
|
const propertyListPopupRef = ref()
|
||
|
|
||
|
const onClosePopup = () => {
|
||
|
propertyListPopupRef.value.close()
|
||
|
}
|
||
|
|
||
|
function chooseProperty(item) {
|
||
|
const index = props.modelValue.findIndex((v) => v.id === item.id)
|
||
|
item.checked = !item.checked
|
||
|
if (index === -1) {
|
||
|
props.modelValue.push(item)
|
||
|
} else {
|
||
|
props.modelValue.splice(index, 1)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function onConfirmPopup() {
|
||
|
emit('update:modelValue', propertyList.value.filter((item) => item.checked).map((item) => item.id) ?? [])
|
||
|
onClosePopup()
|
||
|
}
|
||
|
|
||
|
function onOpen() {
|
||
|
propertyList.value.map((item) => {
|
||
|
item.checked = false
|
||
|
return item
|
||
|
})
|
||
|
propertyList.value = propertyList.value.map((item) =>
|
||
|
props.modelValue.some((id) => id === item.id) ? { ...item, checked: true } : item
|
||
|
)
|
||
|
propertyListPopupRef.value.open('bottom')
|
||
|
}
|
||
|
|
||
|
defineExpose({
|
||
|
onOpen,
|
||
|
})
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
.property-list {
|
||
|
.popup-content {
|
||
|
height: 500rpx;
|
||
|
padding: 40rpx;
|
||
|
display: flex;
|
||
|
flex-wrap: wrap;
|
||
|
gap: 20rpx;
|
||
|
justify-content: flex-start;
|
||
|
.property-item {
|
||
|
text-align: center;
|
||
|
line-height: 60rpx;
|
||
|
height: 60rpx;
|
||
|
padding: 0 10px;
|
||
|
border-radius: 10px;
|
||
|
background-color: var(--ui-BG-4);
|
||
|
}
|
||
|
.active {
|
||
|
color: #fff;
|
||
|
background-color: var(--ui-BG-Main);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.button-link {
|
||
|
color: #1892ea;
|
||
|
font-size: 28rpx;
|
||
|
}
|
||
|
.button-cancel {
|
||
|
color: #888;
|
||
|
font-size: 28rpx;
|
||
|
}
|
||
|
.popup-header {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: space-between;
|
||
|
padding: 24rpx 38rpx 0;
|
||
|
}
|
||
|
}
|
||
|
</style>
|