| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <template>
- <slot />
- </template>
- <script setup lang="ts">
- import { onMounted, onUpdated, provide, toRef, type Ref } from 'vue';
- import { ArrayUtils } from '@imengyu/imengyu-utils';
- import { useFieldChildValueInjector } from './FormContext';
- export interface CheckBoxGroupProps {
- /**
- * 当前复选框组选中的项目
- */
- modelValue?: string[];
- /**
- * 是否禁用整组复选框,设置后会禁用全部复选框。
- * @default false
- */
- disabled?: boolean;
- /**
- * 是否支持多选。仅限制用户选择,通过代码设置值时,不受到此限制。
- * @default true
- */
- multiple?: boolean;
- }
- export interface CheckBoxGroupInterface {
- /**
- * 切换所有复选框
- * @param options 传 true 为选中,false 为取消选中,不传参为取反
- */
- toggleAll: (options?: boolean | undefined | CheckBoxGroupToggleOptions) => void;
- }
- export interface CheckBoxGroupToggleOptions {
- /**
- * 是否是选中
- * @required true
- */
- checked: boolean,
- /**
- * 是否跳过禁用的复选框
- * @required true
- */
- skipDisabled: boolean,
- }
- export interface CheckBoxGroupContextInfo {
- value: Ref<string[]>,
- disabled: Ref<boolean>,
- onValueChange: (name: string|undefined, v: boolean) => void;
- onAddItem: (name: string, disabled: boolean) => void;
- }
- const props = withDefaults(defineProps<CheckBoxGroupProps>(), {
- modelValue: () => [] ,
- disabled: false,
- multiple: true,
- });
- const {
- value,
- updateValue,
- } = useFieldChildValueInjector(
- toRef(props, 'modelValue'),
- (v) => emit('update:modelValue', v)
- );
- provide<CheckBoxGroupContextInfo>('checkBoxGroupContext', {
- value: value,
- disabled: toRef(props, 'disabled'),
- onValueChange,
- onAddItem: (name, disabled) => {
- allCheck.set(name, disabled);
- },
- });
- const emit = defineEmits([ 'update:modelValue' ]);
- const allCheck = new Map<string, boolean>();
- function onValueChange(name: string|undefined, checked: boolean) {
- if (checked && !props.multiple) {
- updateValue([name as string]);
- return;
- }
- const valueNew = (value.value || []).concat();
- if (checked)
- ArrayUtils.addOnce(valueNew, name as string);
- else
- ArrayUtils.remove(valueNew, name as string);
- updateValue(valueNew);
- }
- function toggleAll(options?: boolean|undefined|CheckBoxGroupToggleOptions) {
- const allCheckNames = Array.from(allCheck.keys());
- if (typeof options === 'undefined') {
- //反选
- const valueNew = allCheckNames.filter((i) => value ? !value.value.includes(i) : false);
- updateValue(valueNew);
- } else if (typeof options === 'boolean') {
- //选中/取消选中
- const valueNew = options === true ? allCheckNames.concat() : [];
- updateValue(valueNew);
- } else if (typeof options === 'object') {
- //根据参数,选择时跳过禁用的选项
- const valueNew = allCheckNames.filter((name) => {
- if (options.skipDisabled && allCheck.get(name))
- return value ? value.value.includes(name) : false;
- return options.checked;
- });
- updateValue(valueNew);
- }
- }
- defineOptions({
- options: {
- styleIsolation: "shared",
- virtualHost: true,
- }
- })
- defineExpose<CheckBoxGroupInterface>({
- toggleAll,
- })
- </script>
|