zs
2025-05-06 55bf797dcc730b37bc691ebab2b51ff9db8ed245
HIAWms/web/src/components/Radio/Radio.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,217 @@
import { defineComponent, computed, SetupContext } from 'vue'
import styles from './Radio.module.scss'
import Empty from '../Empty/Empty'
import Icon from '../Icon/Icon'
interface OptionType {
  label: string
  value: string
  name: string
}
interface DataType {
  name?: string
  label?: string
  value?: string
  description?: string
  type?: string
}
interface TagProps {
  data: DataType[]
  options: OptionType[]
  modelValue: string
  [key: string]: any
}
export default defineComponent<TagProps>({
  // @ts-ignore
  name: 'Tag',
  emits: ['click', 'update:modelValue', 'change', 'update:data'],
  props: {
    data: {
      type: [Array, Object],
      default: null,
    },
    options: {
      type: Array,
      default: null,
    },
    modelValue: {
      type: [String, Number],
      default: '',
    },
    trigger: {
      type: String,
      default: 'hover',
    },
    showClose: {
      type: Boolean,
      default: false,
    },
    labelWidth: {
      type: String,
      default: '100px',
    },
  },
  setup(props: TagProps, { attrs, slots, emit }: SetupContext) {
    const modelData = computed({
      get() {
        return props.modelValue
      },
      set(value) {
        emit('update:modelValue', value)
      },
    })
    console.log('modelData', modelData.value)
    const data = computed({
      get() {
        return props.data
      },
      set(value) {
        emit('update:data', value)
      },
    })
    /**
     * æ ¹æ®value查找label
     * @param value
     * @returns
     */
    const findOptionLabelByValue = (value: string) => {
      const item: any = props.options.find((item) => item.value === value)
      console.log('item', item)
      return item?.label || item?.name || ''
    }
    /**
     * é€‰æ‹©
     * @param v
     */
    const onCommand = (v: any) => {
      modelData.value = findOptionLabelByValue(v) || v
      emit('change', v)
    }
    /**
     * å½“v-model:data时,生效
     */
    const onClose = (item: DataType, evt: Event) => {
      evt?.stopPropagation()
      data.value = data.value.filter((i) => i !== item)
    }
    /**
     * click
     * @param evt Event
     */
    const onClick = (evt: Event) => {
      evt?.stopPropagation()
      emit('click', evt)
    }
    console.log(props.data, props.modelValue)
    return () => {
      // å¤štag情况,传data[]
      if (Array.isArray(props.data)) {
        return props.data.map((item: DataType, index: any) => {
          return (
            <div
              class={styles.tag}
              style="margin-right: 5px;cursor: initial;"
              key={index}
              onClick={onClick}
            >
              {item.name || item.label || item.description || item.type}
              {props.showClose ? (
                <Icon
                  class={styles.tagClose}
                  icon="tag_close"
                  width={8}
                  height={8}
                  onClick={(evt) => onClose(item, evt)}
                />
              ) : null}
            </div>
          )
        })
      }
      // ä¸‹æ‹‰é€‰æ‹©hover
      if (Array.isArray(props.options)) {
        return (
          <el-tooltip
            effect="dark"
            content={
              modelData.value
                ? findOptionLabelByValue(modelData.value)
                : '请选择'
            }
            placement="top"
          >
            <el-dropdown
              trigger={props.trigger}
              popperClass={styles.dropdown}
              onCommand={onCommand}
              placement="bottom-start"
              max-height={500}
              vSlots={{
                dropdown: () =>
                  props.options.length ? (
                    <el-dropdown-menu>
                      {props.options.map((item: OptionType) => {
                        return (
                          <el-dropdown-item command={item.value}>
                            <div class={styles.lineTag}>
                              <div class={styles.fitTag}>
                                {' '}
                                {item.label || item.name}
                              </div>
                            </div>
                          </el-dropdown-item>
                        )
                      })}
                    </el-dropdown-menu>
                  ) : (
                    <Empty />
                  ),
              }}
            >
              {modelData.value ? (
                <div
                  class={styles.tag}
                  style={{ width: props.labelWidth }}
                  onClick={() => emit('click')}
                >
                  {findOptionLabelByValue(modelData.value)}
                </div>
              ) : (
                <div
                  class={[styles.tag, styles.pl]}
                  style={{ width: props.labelWidth }}
                >
                  è¯·é€‰æ‹©
                </div>
              )}
            </el-dropdown>
          </el-tooltip>
        )
      }
      // é»˜è®¤åªå±•示一个tag
      return (
        <div
          class={styles.tag}
          style={{ width: props.labelWidth }}
          onClick={() => emit('click')}
        >
          {slots.default && slots.default()}
          {/* {props.showClose ? (
            <Icon
              class={styles.tagClose}
              icon="tag_close"
              width={8}
              height={8}
              onClick={(evt) => onClose(item, evt)}
            />
          ) : null} */}
        </div>
      )
    }
  },
})