1
This commit is contained in:
196
src/components/tables/fieldRenderer.vue
Normal file
196
src/components/tables/fieldRenderer.vue
Normal file
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 使用组件映射表来简化条件渲染 -->
|
||||
<component
|
||||
:is="getComponentName(col.com)"
|
||||
v-model="value"
|
||||
v-bind="getComponentProps(col)"
|
||||
:disabled="disabled"
|
||||
:class="getComponentClass(col.com)"
|
||||
:style="getComponentStyle(col.com)"
|
||||
@input="handleInput"
|
||||
@change="handleChange"
|
||||
>
|
||||
<!-- Select 组件的选项 -->
|
||||
<template v-if="col.com === 'Select'">
|
||||
<Option
|
||||
:value="item.key"
|
||||
:key="item.key"
|
||||
v-for="item in col.source"
|
||||
>
|
||||
{{ item.value }}
|
||||
</Option>
|
||||
</template>
|
||||
|
||||
<!-- Radio 组件的选项 -->
|
||||
<template v-else-if="col.com === 'Radio'">
|
||||
<Radio
|
||||
:label="item.key"
|
||||
:key="item.key"
|
||||
v-for="item in col.source"
|
||||
>
|
||||
{{ item.value }}
|
||||
</Radio>
|
||||
</template>
|
||||
|
||||
<!-- SelectIcon 组件的选项 -->
|
||||
<template v-else-if="col.com === 'SelectIcon'">
|
||||
<Option
|
||||
v-for="(icon, index) in icons"
|
||||
:value="icon"
|
||||
:key="index"
|
||||
>
|
||||
<Icon size="20" :type="icon" />
|
||||
{{ icon }}
|
||||
</Option>
|
||||
</template>
|
||||
|
||||
<!-- 自定义渲染 -->
|
||||
<template v-else-if="col.editRender">
|
||||
<templateRender
|
||||
:value="value"
|
||||
:render="col.editRender"
|
||||
/>
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import templateRender from './templateRender'
|
||||
|
||||
// 导入框架中的图标配置
|
||||
let icons = []
|
||||
try {
|
||||
icons = require('../../config/icons.json') || []
|
||||
} catch (e) {
|
||||
console.warn('未找到图标配置文件,图标选择功能将不可用', e)
|
||||
icons = []
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'FieldRenderer',
|
||||
components: {
|
||||
templateRender
|
||||
},
|
||||
props: {
|
||||
col: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
value: {
|
||||
type: [String, Number, Boolean, Array, Object, Date],
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
icons: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 安全处理图标数据
|
||||
if (Array.isArray(icons)) {
|
||||
this.icons = icons.map((item) => item.trim ? item.trim() : item)
|
||||
} else {
|
||||
this.icons = []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 组件映射表 - 统一管理组件类型
|
||||
getComponentName(componentType) {
|
||||
const componentMap = {
|
||||
'Select': 'Select',
|
||||
'Radio': 'RadioGroup',
|
||||
'SelectIcon': 'AutoComplete',
|
||||
'UploadSingle': 'UploadSingle',
|
||||
'TextArea': 'TextArea',
|
||||
'Input': 'Input',
|
||||
'DatePicker': 'DatePicker',
|
||||
'TimePicker': 'TimePicker',
|
||||
'Switch': 'Switch',
|
||||
'Checkbox': 'Checkbox',
|
||||
'Slider': 'Slider',
|
||||
'Rate': 'Rate',
|
||||
'Cascader': 'Cascader',
|
||||
'TreeSelect': 'TreeSelect',
|
||||
'Transfer': 'Transfer',
|
||||
'Upload': 'Upload',
|
||||
'ColorPicker': 'ColorPicker',
|
||||
'InputNumber': 'InputNumber'
|
||||
}
|
||||
|
||||
// 如果没有指定组件类型,默认为 Input
|
||||
return componentMap[componentType] || 'Input'
|
||||
},
|
||||
|
||||
// 获取组件属性
|
||||
getComponentProps(col) {
|
||||
const baseProps = { ...col }
|
||||
|
||||
// 移除不需要传递给组件的属性
|
||||
delete baseProps.com
|
||||
delete baseProps.source
|
||||
delete baseProps.editRender
|
||||
delete baseProps.inLine
|
||||
delete baseProps.display
|
||||
delete baseProps.disabled
|
||||
delete baseProps.disabledOnAdd
|
||||
delete baseProps.required
|
||||
delete baseProps.data_type
|
||||
delete baseProps.type
|
||||
delete baseProps.rowStyle
|
||||
|
||||
// 根据组件类型添加特定属性
|
||||
if (col.com === 'Select') {
|
||||
baseProps.filterable = true
|
||||
baseProps.clearable = true
|
||||
} else if (col.com === 'SelectIcon') {
|
||||
baseProps.icon = 'ios-search'
|
||||
} else if (col.com === 'TextArea') {
|
||||
baseProps.rows = 4
|
||||
baseProps.placeholder = '请输入内容'
|
||||
} else if (col.com === 'Input' || !col.com) {
|
||||
baseProps.placeholder = col.placeholder || '请输入' + col.title
|
||||
baseProps.clearable = true
|
||||
}
|
||||
|
||||
return baseProps
|
||||
},
|
||||
|
||||
// 获取组件样式类
|
||||
getComponentClass(componentType) {
|
||||
const classMap = {
|
||||
'Select': 'text-left',
|
||||
'SelectIcon': 'text-left'
|
||||
}
|
||||
return classMap[componentType] || ''
|
||||
},
|
||||
|
||||
// 获取组件样式
|
||||
getComponentStyle(componentType) {
|
||||
const styleMap = {
|
||||
'Input': 'width:100%;',
|
||||
'TextArea': 'width:100%;',
|
||||
'DatePicker': 'width:100%;',
|
||||
'TimePicker': 'width:100%;'
|
||||
}
|
||||
return styleMap[componentType] || ''
|
||||
},
|
||||
|
||||
// 处理输入事件
|
||||
handleInput(value) {
|
||||
this.$emit('input', value)
|
||||
},
|
||||
|
||||
// 处理变化事件
|
||||
handleChange(value) {
|
||||
this.$emit('change', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user