77 lines
1.6 KiB
Vue
77 lines
1.6 KiB
Vue
<template>
|
|
<view class="checkbox-group" :style="`${checkgroupStyle}`">
|
|
<slot></slot>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { provide, computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
modelValue: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
max: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
checkgroupStyle:{
|
|
type:String,
|
|
default:'grid-template-columns: repeat(3, 1fr);'
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['update:modelValue', 'change'])
|
|
|
|
// 内部维护一个响应式的值
|
|
const innerValue = computed(() => props.modelValue)
|
|
|
|
// 切换选项
|
|
const toggleOption = (option: { label: string; value: string | number }) => {
|
|
const currentValue = innerValue.value
|
|
const index = currentValue.indexOf(option.value)
|
|
let newValue = [...currentValue]
|
|
|
|
if (index === -1) {
|
|
if (props.max === 1) {
|
|
newValue = [option.value]
|
|
} else if (props.max && currentValue.length >= props.max) {
|
|
uni.showToast({
|
|
title: `最多只能选择${props.max}项`,
|
|
icon: 'none',
|
|
})
|
|
return
|
|
} else {
|
|
newValue.push(option.value)
|
|
}
|
|
} else {
|
|
newValue.splice(index, 1)
|
|
}
|
|
|
|
emit('update:modelValue', newValue)
|
|
emit('change', newValue)
|
|
}
|
|
|
|
// 提供给checkbox的上下文
|
|
provide('checkboxGroup', {
|
|
modelValue: computed(() => props.modelValue),
|
|
disabled: computed(() => props.disabled),
|
|
max: computed(() => props.max),
|
|
selectedCount: computed(() => props.modelValue.length),
|
|
toggleOption,
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
|
|
.checkbox-group{
|
|
display: grid;
|
|
gap: 16rpx;
|
|
}
|
|
</style>
|