¶Ô±ÈÐÂÎļþ |
| | |
| | | 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> |
| | | ) |
| | | } |
| | | }, |
| | | }) |