parent
							
								
									ea776aa710
								
							
						
					
					
						commit
						4102cc2211
					
				|  | @ -29,14 +29,25 @@ export type ValueType = boolean | number | string; | |||
| 
 | ||||
| export interface VbenButtonGroupProps | ||||
|   extends Pick<VbenButtonProps, 'disabled'> { | ||||
|   /** 单选模式下允许清除选中 */ | ||||
|   allowClear?: boolean; | ||||
|   /** 值改变前的回调 */ | ||||
|   beforeChange?: ( | ||||
|     value: ValueType, | ||||
|     isChecked: boolean, | ||||
|   ) => boolean | PromiseLike<boolean | undefined> | undefined; | ||||
|   /** 按钮样式 */ | ||||
|   btnClass?: any; | ||||
|   /** 按钮间隔距离 */ | ||||
|   gap?: number; | ||||
|   /** 多选模式下限制最多选择的数量。0表示不限制 */ | ||||
|   maxCount?: number; | ||||
|   /** 是否允许多选 */ | ||||
|   multiple?: boolean; | ||||
|   /** 选项 */ | ||||
|   options?: { [key: string]: any; label: CustomRenderType; value: ValueType }[]; | ||||
|   /** 显示图标 */ | ||||
|   showIcon?: boolean; | ||||
|   /** 尺寸 */ | ||||
|   size?: 'large' | 'middle' | 'small'; | ||||
| } | ||||
|  |  | |||
|  | @ -19,6 +19,8 @@ const props = withDefaults(defineProps<VbenButtonGroupProps>(), { | |||
|   multiple: false, | ||||
|   showIcon: true, | ||||
|   size: 'middle', | ||||
|   allowClear: false, | ||||
|   maxCount: 0, | ||||
| }); | ||||
| const emit = defineEmits(['btnClick']); | ||||
| const btnDefaultProps = computed(() => { | ||||
|  | @ -82,12 +84,22 @@ async function onBtnClick(value: ValueType) { | |||
|     if (innerValue.value.includes(value)) { | ||||
|       innerValue.value = innerValue.value.filter((item) => item !== value); | ||||
|     } else { | ||||
|       if (props.maxCount > 0 && innerValue.value.length >= props.maxCount) { | ||||
|         innerValue.value = innerValue.value.slice(0, props.maxCount - 1); | ||||
|       } | ||||
|       innerValue.value.push(value); | ||||
|     } | ||||
|     modelValue.value = innerValue.value; | ||||
|   } else { | ||||
|     innerValue.value = [value]; | ||||
|     modelValue.value = value; | ||||
|     if (props.allowClear && innerValue.value.includes(value)) { | ||||
|       innerValue.value = []; | ||||
|       modelValue.value = undefined; | ||||
|       emit('btnClick', undefined); | ||||
|       return; | ||||
|     } else { | ||||
|       innerValue.value = [value]; | ||||
|       modelValue.value = value; | ||||
|     } | ||||
|   } | ||||
|   emit('btnClick', value); | ||||
| } | ||||
|  | @ -112,12 +124,18 @@ async function onBtnClick(value: ValueType) { | |||
|       @click="onBtnClick(btn.value)" | ||||
|     > | ||||
|       <div class="icon-wrapper" v-if="props.showIcon"> | ||||
|         <LoaderCircle | ||||
|           class="animate-spin" | ||||
|           v-if="loadingValues.includes(btn.value)" | ||||
|         /> | ||||
|         <CircleCheckBig v-else-if="innerValue.includes(btn.value)" /> | ||||
|         <Circle v-else /> | ||||
|         <slot | ||||
|           name="icon" | ||||
|           :loading="loadingValues.includes(btn.value)" | ||||
|           :checked="innerValue.includes(btn.value)" | ||||
|         > | ||||
|           <LoaderCircle | ||||
|             class="animate-spin" | ||||
|             v-if="loadingValues.includes(btn.value)" | ||||
|           /> | ||||
|           <CircleCheckBig v-else-if="innerValue.includes(btn.value)" /> | ||||
|           <Circle v-else /> | ||||
|         </slot> | ||||
|       </div> | ||||
|       <slot name="option" :label="btn.label" :value="btn.value" :data="btn"> | ||||
|         <VbenRenderContent :content="btn.label" /> | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ import { | |||
|   VbenButtonGroup, | ||||
|   VbenCheckButtonGroup, | ||||
| } from '@vben/common-ui'; | ||||
| import { LoaderCircle, Square, SquareCheckBig } from '@vben/icons'; | ||||
| 
 | ||||
| import { Button, Card, message } from 'ant-design-vue'; | ||||
| 
 | ||||
|  | @ -51,6 +52,7 @@ const compProps = reactive({ | |||
|   gap: 0, | ||||
|   showIcon: true, | ||||
|   size: 'middle', | ||||
|   allowClear: false, | ||||
| } as Recordable<any>); | ||||
| 
 | ||||
| const [Form] = useVbenForm({ | ||||
|  | @ -63,6 +65,9 @@ const [Form] = useVbenForm({ | |||
|       } | ||||
|     }); | ||||
|   }, | ||||
|   commonConfig: { | ||||
|     labelWidth: 150, | ||||
|   }, | ||||
|   schema: [ | ||||
|     { | ||||
|       component: 'RadioGroup', | ||||
|  | @ -109,6 +114,20 @@ const [Form] = useVbenForm({ | |||
|       fieldName: 'beforeChange', | ||||
|       label: '前置回调', | ||||
|     }, | ||||
|     { | ||||
|       component: 'Switch', | ||||
|       defaultValue: false, | ||||
|       fieldName: 'allowClear', | ||||
|       label: '允许清除', | ||||
|       help: '单选时是否允许取消选中(值为undefined)', | ||||
|     }, | ||||
|     { | ||||
|       component: 'InputNumber', | ||||
|       defaultValue: 0, | ||||
|       fieldName: 'maxCount', | ||||
|       label: '最大选中数量', | ||||
|       help: '多选时有效,0表示不限制', | ||||
|     }, | ||||
|   ], | ||||
|   showDefaultActions: false, | ||||
|   submitOnChange: true, | ||||
|  | @ -186,6 +205,21 @@ function onBtnClick(value: any) { | |||
|           v-bind="compProps" | ||||
|         /> | ||||
|       </div> | ||||
|       <p class="mt-4">自定义图标{{ checkValue }}</p> | ||||
|       <div class="mt-2 flex flex-col gap-2"> | ||||
|         <VbenCheckButtonGroup | ||||
|           v-model="checkValue" | ||||
|           multiple | ||||
|           :options="options" | ||||
|           v-bind="compProps" | ||||
|         > | ||||
|           <template #icon="{ loading, checked }"> | ||||
|             <LoaderCircle class="animate-spin" v-if="loading" /> | ||||
|             <SquareCheckBig v-else-if="checked" /> | ||||
|             <Square v-else /> | ||||
|           </template> | ||||
|         </VbenCheckButtonGroup> | ||||
|       </div> | ||||
|     </Card> | ||||
| 
 | ||||
|     <Card title="设置" class="mt-4"> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Netfan
						Netfan