This commit is contained in:
吴红兵
2026-03-07 01:34:48 +08:00
parent adc511cfdc
commit 94c3473958
1211 changed files with 599405 additions and 322105 deletions

View File

@@ -11,20 +11,20 @@
## Props
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|------|------|------|--------|------|
| value | 当前状态值 | `string \| number` | `''` | 是 |
| options | 选项列表,格式:`[{label: '是', value: '1'}, {label: '否', value: '0'}]` | `Option[]` | `[]` | 是 |
| showTag | 是否显示标签样式(有边框和背景),`false` 为纯文本样式 | `boolean` | `true` | 否 |
| typeMap | 自定义类型映射,用于标签模式,如:`{'1': {type: 'warning', effect: 'dark'}}` | `Record<string \| number, { type: string; effect?: string }>` | `{}` | 否 |
| colorMap | 自定义颜色映射,用于纯文本模式,如:`{'1': '#E6A23C'}` | `Record<string \| number, string>` | `{}` | 否 |
| 参数 | 说明 | 类型 | 默认值 | 必填 |
| -------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------- | ------ | ---- |
| value | 当前状态值 | `string \| number` | `''` | 是 |
| options | 选项列表,格式:`[{label: '是', value: '1'}, {label: '否', value: '0'}]` | `Option[]` | `[]` | 是 |
| showTag | 是否显示标签样式(有边框和背景),`false` 为纯文本样式 | `boolean` | `true` | 否 |
| typeMap | 自定义类型映射,用于标签模式,如:`{'1': {type: 'warning', effect: 'dark'}}` | `Record<string \| number, { type: string; effect?: string }>` | `{}` | 否 |
| colorMap | 自定义颜色映射,用于纯文本模式,如:`{'1': '#E6A23C'}` | `Record<string \| number, string>` | `{}` | 否 |
### Option 接口
```typescript
interface Option {
label: string // 显示文本
value: string | number // 选项值
label: string; // 显示文本
value: string | number; // 选项值
}
```
@@ -35,8 +35,8 @@ interface Option {
- **值 '1' 或 1**
- 标签模式:`warning` 类型 + `dark` 效果(橙色深色)
- 纯文本模式:`var(--el-color-warning)`(橙色)
- **值 '0' 或 0**
- 标签模式:`primary` 类型 + `light` 效果(蓝色浅色)
- 纯文本模式:`var(--el-color-primary)`(蓝色)
@@ -50,56 +50,49 @@ interface Option {
```vue
<template>
<StatusTag
:value="scope.row.tied"
:options="YES_OR_NO"
/>
<StatusTag :value="scope.row.tied" :options="YES_OR_NO" />
</template>
<script setup>
import StatusTag from '/@/components/StatusTag/index.vue'
import StatusTag from '/@/components/StatusTag/index.vue';
const YES_OR_NO = [
{ label: '是', value: '1' },
{ label: '否', value: '0' }
]
{ label: '是', value: '1' },
{ label: '否', value: '0' },
];
</script>
```
### 纯文本模式(无边框和背景)
```vue
<StatusTag
:value="scope.row.tied"
:options="YES_OR_NO"
:show-tag="false"
/>
<StatusTag :value="scope.row.tied" :options="YES_OR_NO" :show-tag="false" />
```
### 自定义类型映射
```vue
<StatusTag
:value="scope.row.status"
:options="statusOptions"
:type-map="{
'1': { type: 'success', effect: 'dark' },
'0': { type: 'danger', effect: 'light' }
}"
<StatusTag
:value="scope.row.status"
:options="statusOptions"
:type-map="{
'1': { type: 'success', effect: 'dark' },
'0': { type: 'danger', effect: 'light' },
}"
/>
```
### 自定义颜色映射(纯文本模式)
```vue
<StatusTag
:value="scope.row.status"
:options="statusOptions"
:show-tag="false"
:color-map="{
'1': '#67C23A',
'0': '#F56C6C'
}"
<StatusTag
:value="scope.row.status"
:options="statusOptions"
:show-tag="false"
:color-map="{
'1': '#67C23A',
'0': '#F56C6C',
}"
/>
```
@@ -107,24 +100,21 @@ const YES_OR_NO = [
```vue
<template>
<el-table :data="tableData">
<el-table-column label="是否退休" width="100" align="center">
<template #default="scope">
<StatusTag
:value="scope.row.tied"
:options="YES_OR_NO"
/>
</template>
</el-table-column>
</el-table>
<el-table :data="tableData">
<el-table-column label="是否退休" width="100" align="center">
<template #default="scope">
<StatusTag :value="scope.row.tied" :options="YES_OR_NO" />
</template>
</el-table-column>
</el-table>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from 'vue'
import global from '/@/components/tools/commondict.vue'
import { defineAsyncComponent } from 'vue';
import global from '/@/components/tools/commondict.vue';
const StatusTag = defineAsyncComponent(() => import('/@/components/StatusTag/index.vue'))
const YES_OR_NO = global.YES_OR_NO
const StatusTag = defineAsyncComponent(() => import('/@/components/StatusTag/index.vue'));
const YES_OR_NO = global.YES_OR_NO;
</script>
```
@@ -140,10 +130,10 @@ const YES_OR_NO = global.YES_OR_NO
### 标签模式showTag: true
使用 Element Plus 的 `el-tag` 组件,支持所有 `el-tag` 的类型和效果:
- `type`: `success` | `info` | `warning` | `danger` | `primary`
- `effect`: `dark` | `light` | `plain`
### 纯文本模式showTag: false
使用纯文本显示,通过 CSS 颜色控制样式支持任何颜色值CSS 变量、十六进制、RGB 等)。

View File

@@ -1,140 +1,135 @@
<template>
<el-tag
v-if="showTag"
:type="tagType"
:effect="tagEffect"
>
{{ label }}
</el-tag>
<span v-else class="status-tag" :class="statusClass" :style="statusStyle">
{{ label }}
</span>
<el-tag v-if="showTag" :type="tagType" :effect="tagEffect">
{{ label }}
</el-tag>
<span v-else class="status-tag" :class="statusClass" :style="statusStyle">
{{ label }}
</span>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { computed } from 'vue';
interface Option {
label: string
value: string | number
label: string;
value: string | number;
}
interface Props {
value?: string | number // 当前值
options?: Option[] // 选项列表,格式:[{label: '是', value: '1'}, {label: '否', value: '0'}]
showTag?: boolean // 是否显示标签样式(有边框和背景),默认为 true
typeMap?: Record<string | number, { type: string; effect?: string }> // 自定义类型映射,如 {'1': {type: 'warning', effect: 'dark'}}
colorMap?: Record<string | number, string> // 纯文本模式下的颜色映射,如 {'1': '#E6A23C'}
value?: string | number; // 当前值
options?: Option[]; // 选项列表,格式:[{label: '是', value: '1'}, {label: '否', value: '0'}]
showTag?: boolean; // 是否显示标签样式(有边框和背景),默认为 true
typeMap?: Record<string | number, { type: string; effect?: string }>; // 自定义类型映射,如 {'1': {type: 'warning', effect: 'dark'}}
colorMap?: Record<string | number, string>; // 纯文本模式下的颜色映射,如 {'1': '#E6A23C'}
}
const props = withDefaults(defineProps<Props>(), {
value: '',
options: () => [],
showTag: true,
typeMap: () => ({}),
colorMap: () => ({})
})
value: '',
options: () => [],
showTag: true,
typeMap: () => ({}),
colorMap: () => ({}),
});
// 默认的类型映射(只使用字符串键)
const defaultTypeMap: Record<string, { type: string; effect: string }> = {
'1': { type: 'danger', effect: 'dark' },
'0': { type: 'primary', effect: 'light' }
}
'1': { type: 'danger', effect: 'dark' },
'0': { type: 'primary', effect: 'light' },
};
// 默认的颜色映射(只使用字符串键)
const defaultColorMap: Record<string, string> = {
'1': 'var(--el-color-danger)',
'0': 'var(--el-color-primary)'
}
'1': 'var(--el-color-danger)',
'0': 'var(--el-color-primary)',
};
// 获取值的字符串形式(用于查找映射)
const getValueKey = (value: string | number): string => {
return String(value)
}
return String(value);
};
// 合并后的类型映射(外部传入优先,否则使用默认)
const mergedTypeMap = computed(() => {
// 将外部传入的 typeMap 也转换为字符串键
const externalTypeMap: Record<string, { type: string; effect?: string }> = {}
Object.keys(props.typeMap).forEach(key => {
externalTypeMap[String(key)] = props.typeMap[key]
})
return { ...defaultTypeMap, ...externalTypeMap }
})
// 将外部传入的 typeMap 也转换为字符串键
const externalTypeMap: Record<string, { type: string; effect?: string }> = {};
Object.keys(props.typeMap).forEach((key) => {
externalTypeMap[String(key)] = props.typeMap[key];
});
return { ...defaultTypeMap, ...externalTypeMap };
});
// 合并后的颜色映射(外部传入优先,否则使用默认)
const mergedColorMap = computed(() => {
// 将外部传入的 colorMap 也转换为字符串键
const externalColorMap: Record<string, string> = {}
Object.keys(props.colorMap).forEach(key => {
externalColorMap[String(key)] = props.colorMap[key]
})
return { ...defaultColorMap, ...externalColorMap }
})
// 将外部传入的 colorMap 也转换为字符串键
const externalColorMap: Record<string, string> = {};
Object.keys(props.colorMap).forEach((key) => {
externalColorMap[String(key)] = props.colorMap[key];
});
return { ...defaultColorMap, ...externalColorMap };
});
// 合并后的选项列表(必须通过外部传入 options
const mergedOptions = computed(() => {
// 必须传入 options否则返回空数组
return props.options && props.options.length > 0 ? props.options : []
})
// 必须传入 options否则返回空数组
return props.options && props.options.length > 0 ? props.options : [];
});
// 根据值找到对应的选项
const currentOption = computed(() => {
return mergedOptions.value.find((opt: Option) => {
const optValue = String(opt.value)
const propValue = String(props.value)
return optValue === propValue || Number(opt.value) === Number(props.value)
})
})
return mergedOptions.value.find((opt: Option) => {
const optValue = String(opt.value);
const propValue = String(props.value);
return optValue === propValue || Number(opt.value) === Number(props.value);
});
});
// 显示标签
const label = computed(() => {
return currentOption.value?.label || '-'
})
return currentOption.value?.label || '-';
});
// 标签类型showTag 为 true 时使用)
const tagType = computed(() => {
const valueKey = getValueKey(props.value)
if (mergedTypeMap.value[valueKey]) {
return mergedTypeMap.value[valueKey].type
}
return 'info'
})
const valueKey = getValueKey(props.value);
if (mergedTypeMap.value[valueKey]) {
return mergedTypeMap.value[valueKey].type;
}
return 'info';
});
// 标签效果showTag 为 true 时使用)
const tagEffect = computed(() => {
const valueKey = getValueKey(props.value)
if (mergedTypeMap.value[valueKey]?.effect) {
return mergedTypeMap.value[valueKey].effect
}
return 'light'
})
const valueKey = getValueKey(props.value);
if (mergedTypeMap.value[valueKey]?.effect) {
return mergedTypeMap.value[valueKey].effect;
}
return 'light';
});
// 纯文本模式下的样式类
const statusClass = computed(() => {
if (props.colorMap[props.value]) {
return ''
}
return 'status-default'
})
if (props.colorMap[props.value]) {
return '';
}
return 'status-default';
});
// 纯文本模式下的内联样式
const statusStyle = computed(() => {
const valueKey = getValueKey(props.value)
if (mergedColorMap.value[valueKey]) {
return { color: mergedColorMap.value[valueKey] }
}
return {}
})
const valueKey = getValueKey(props.value);
if (mergedColorMap.value[valueKey]) {
return { color: mergedColorMap.value[valueKey] };
}
return {};
});
</script>
<style scoped>
.status-tag {
display: inline-block;
display: inline-block;
}
.status-default {
color: var(--el-text-color-regular);
color: var(--el-text-color-regular);
}
</style>