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>
|