You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

137 lines
3.3 KiB

<template>
<el-form-item :class="[{ 'column': column }, 'form-item']" :label="label" :prop="prop" :rules="rules"
:required="required">
<el-radio-group v-model="selectedValue" v-bind="$attrs" @change="handleChange">
<el-radio v-for="(optionValue, optionKey) in normalizedOptions" :key="optionKey"
:label="getValue(optionValue)" :disabled="isDisabled(optionValue[valueKey])">
{{ getLabel(optionValue) }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<script>
export default {
name: 'MyRadioGroup',
props: {
// 是否是纵向排列
column: {
type: String,
default: ''
},
required: {
type: Boolean,
default: false
},
// 选项列表,支持多种格式:
// 1. 数组格式: [{ label: '显示文本', value: '值', disabled: false }]
// 2. 对象格式: { key1: 'value1', key2: 'value2' }
options: {
type: [Array, Object],
required: true,
},
// 当前选中的值,使用 v-model 绑定
value: {
type: [String, Number, Boolean],
default: '',
},
// 表单项的 label
label: {
type: String,
default: '',
},
// 表单项的 prop(用于表单校验)
prop: {
type: String,
default: '',
},
// 校验规则
rules: {
type: Array,
default: () => [],
},
labelKey: {
type: String,
default: 'label'
},
// 自定义value的字段名
valueKey: {
type: String,
default: 'value'
},
// 格式化label的函数
formatter: {
type: Function,
default: null
},
// 禁用选项的key数组
disabledKeys: {
type: Array,
default: () => []
}
},
computed: {
// 统一处理数组和对象格式
normalizedOptions() {
// 数组
if (Array.isArray(this.options)) {
return this.options;
} else if (typeof this.options === 'object' && this.options !== null) {
// 将对象格式统一转换为数组
return Object.keys(this.options).map(key => ({
key,
value: this.options[key]
}));
}
return [];
}
},
data() {
return {
selectedValue: this.value, // 内部维护的选中值
};
},
watch: {
// 监听外部传入的 value 变化,更新内部 selectedValue
value(newVal) {
this.selectedValue = newVal;
},
},
methods: {
// 选中值变化时触发
handleChange(value) {
this.$emit('input', value); // 更新 v-model
this.$emit('change', value); // 触发 change 事件
},
getLabel(option) {
if (this.formatter) return this.formatter(option);
// 处理对象格式的选项
if (typeof option === 'object' && 'key' in option && 'value' in option) {
return option.value;
}
return option[this.labelKey] || option;
},
getValue(option) {
// 处理对象格式的选项
if (typeof option === 'object' && 'key' in option && 'value' in option) {
return option.key;
}
return option[this.valueKey] || option;
},
// 判断选项是否禁用
isDisabled(key) {
return this.disabledKeys.includes(key);
}
},
};
</script>
<style scoped>
/* 自定义样式 */
.el-radio-group {
margin: 10px 0;
}
</style>