123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <template>
- <view class="fs-checkbox-group" :class="{ inline }"><slot></slot></view>
- </template>
- <script>
- /**
- * 多选框组组件
- * @description 多选框组组件
- * @property {Number} max 最多选中几个
- * @property {String} justify 图标对齐方式
- * @property {Boolean} reverse 是否反转
- * @property {Boolean} inline 单行显示
- * @property {Boolean} radius 是否圆角(仅对按钮样式有效)
- * @property {Boolean} round 是否半圆(仅对按钮样式有效)
- * @property {String} checkedColor 选中颜色
- * @property {String} checkedColorType = [primary | danger | warning | info | success] 选中颜色类型
- * @property {String} size = [mini | small | medium] 按钮大小(仅对按钮样式有效)
- * @event {Function} change change事件
- */
- export default {
- name: 'fs-checkbox-group'
- }
- </script>
- <script setup>
- import { provide, reactive, watch, toRefs } from 'vue'
- const props = defineProps({
- max: {
- type: Number,
- default: -1
- },
- justify: String,
- reverse: Boolean,
- inline: Boolean,
- checkedColor: String,
- checkedColorType: {
- type: String,
- default: 'primary',
- validator(value) {
- return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
- }
- },
- radius: Boolean,
- round: Boolean,
- size: {
- type: String,
- validator(value) {
- return ['mini', 'small', 'medium'].includes(value)
- }
- },
- modelValue: {
- type: Array,
- default() {
- return []
- }
- }
- })
- const emits = defineEmits(['update:modelValue', 'change'])
- const state = reactive({
- selectedValue: props.modelValue,
- children: []
- })
- watch(
- () => props.modelValue,
- val => {
- state.selectedValue = val
- }
- )
- const checkStrategy = value => {
- state.children.forEach(item => {
- if (typeof item.value === 'object') {
- item.selected = state.selectedValue.filter(selected => selected.id === item.value.id).length > 0
- } else {
- item.selected = state.selectedValue.indexOf(item.value) > -1
- }
- })
- }
- const updateChildren = child => {
- state.children.push(child)
- checkStrategy()
- }
- const updateValue = value => {
- let index = -1
- if (typeof value === 'object') {
- state.selectedValue.forEach((item, key) => {
- if (item.id === value.id) {
- index = key
- }
- })
- } else {
- index = state.selectedValue.indexOf(value)
- }
- if (state.selectedValue.length < props.max || props.max === -1) {
- if (index === -1) {
- state.selectedValue.push(value)
- } else {
- state.selectedValue.splice(index, 1)
- }
- } else {
- index > -1 && state.selectedValue.splice(index, 1)
- }
- }
- watch(
- () => state.selectedValue,
- val => {
- checkStrategy()
- emits('update:modelValue', val)
- emits('change', val)
- },
- { deep: true }
- )
- provide('checkboxGroup', {
- ...toRefs(props),
- updateChildren,
- updateValue
- })
- </script>
- <style lang="scss" scoped>
- .fs-checkbox-group {
- &.inline {
- display: flex;
- flex-wrap: wrap;
- }
- }
- </style>
|