vue3 checkbox 单选

发布时间 2023-07-21 15:57:37作者: 三岔路
<template>
  <div class="ant-checkbox-group ant-checkbox-group-outline">
    <label
      v-for="item in getOptions"
      :key="`${item.value}`"
      :class="getCheckboxwrapperClass(item.value == state, $props.disabled)"
    >
      <span :class="getCheckboxClass(item.value == state, $props.disabled)">
        <input
          type="checkbox"
          class="ant-checkbox-input"
          :value="`${item.value}`"
          :disabled="item.disabled"
          @click="handleChange(item)" />
        <span class="ant-checkbox-inner"></span></span
      ><span>{{ item.label }}</span></label
    >
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, computed, ref } from 'vue';
  import { isString } from '/@/utils/is';
  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
  import { useAttrs } from '/@/hooks/core/useAttrs';

  type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
  type RadioItem = string | OptionsItem;

  export default defineComponent({
    name: 'RadioCheckGroup',
    components: {},
    props: {
      value: {
        type: [String, Number, Boolean] as PropType<string | number | boolean>,
      },
      options: {
        type: Array as PropType<RadioItem[]>,
        default: () => [],
      },
      disabled: {
        type: Boolean as PropType<boolean>,
      },
    },
    emits: ['change', 'update:value'],
    setup(props, { emit }) {
      const emitData = ref<string | number | boolean>();
      const attrs = useAttrs();
      // Embedded in the form, just use the hook binding to perform form verification
      const [state] = useRuleFormItem(props);

      // Processing options value
      const getOptions = computed((): OptionsItem[] => {
        const { options } = props;
        if (!options || options?.length === 0) return [];

        const isStringArr = options.some((item) => isString(item));
        if (!isStringArr) return options as OptionsItem[];

        return options.map((item) => ({ label: item, value: item })) as OptionsItem[];
      });
      function getCheckboxwrapperClass(checked, disabled) {
        let _class = 'ant-checkbox-wrapper';
        if (checked) {
          _class += ' ant-checkbox-wrapper-checked';
        }
        if (disabled) {
          _class += ' ant-checkbox-wrapper-disabled';
        }
        return _class;
      }

      function getCheckboxClass(checked, disabled) {
        let _class = 'ant-checkbox';
        if (checked) {
          _class += ' ant-checkbox-checked';
        }
        if (disabled) {
          _class += ' ant-checkbox-disabled';
        }
        return _class;
      }
      function handleChange(ops: OptionsItem) {
        console.log('handleChange', ops);
        if (state.value == ops.value) {
          state.value = '';
          emitData.value = '';
          emit('change', {});
          emit('update:value', state.value);
        } else {
          emitData.value = ops.value;
          state.value = ops.value;
          emit('change', ops);
          emit('update:value', state.value);
        }
      }
      return { state, getOptions, attrs, getCheckboxwrapperClass, getCheckboxClass, handleChange };
    },
  });
</script>

  使用:

 <RadioCheckGroup
            v-model:value="props.formData.wenxunxx.i_LAIYUANQD"
            :disabled="props.disabled"
            :options="[
              { label: '一网通办', value: 1 },
              { label: '联审平台', value: 2 },
              { label: '供水热线', value: 3 },
              { label: '市民热线', value: 4 },
              { label: '热线网厅', value: 5 },
              { label: '营业厅', value: 6 },
              { label: '其他', value: 7 },
            ]"
          />