1
This commit is contained in:
21
src/components/date-picker/index.vue
Normal file
21
src/components/date-picker/index.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<DatePicker
|
||||
:value="value"
|
||||
v-bind="$attrs"
|
||||
@on-change="handleChange"
|
||||
:style="'width:100%;'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DatePicker',
|
||||
props: ['value'],
|
||||
methods: {
|
||||
handleChange(date) {
|
||||
this.$emit('input', date)
|
||||
this.$emit('change', date)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
84
src/components/index.js
Normal file
84
src/components/index.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import Main from './main'
|
||||
import ParentView from './parent-view'
|
||||
|
||||
// 导入页面组件
|
||||
import pages from '../views/index'
|
||||
const {
|
||||
LoginPage,
|
||||
Page401,
|
||||
Page404,
|
||||
Page500
|
||||
} = pages
|
||||
|
||||
import Tables from './tables'
|
||||
import UploadSingle from './upload/Single.vue'
|
||||
import UploadMultiple from './upload/Multiple.vue'
|
||||
import TreeGrid from './treeGrid'
|
||||
import AsyncModal from './asyncModal'
|
||||
import InfoCard from './info-card'
|
||||
import LoadFlower from './load-flower'
|
||||
import SplitPane from './split-pane'
|
||||
import TextArea from './text-area'
|
||||
import CommonIcon from './common-icon'
|
||||
import Editor from './editor/index.vue'
|
||||
import editModal from './tables/editModal.vue'
|
||||
import fieldItem from './tables/fieldItem.vue'
|
||||
import FieldRenderer from './tables/fieldRenderer.vue'
|
||||
|
||||
|
||||
// 注册全局组件的方法
|
||||
export function registerGlobalComponents(Vue) {
|
||||
Vue.component('Main', Main)
|
||||
Vue.component('ParentView', ParentView)
|
||||
|
||||
Vue.component('Page401', Page401)
|
||||
Vue.component('Page404', Page404)
|
||||
Vue.component('Page500', Page500)
|
||||
|
||||
Vue.component('LoginPage', LoginPage)
|
||||
|
||||
Vue.component('Tables', Tables)
|
||||
Vue.component('UploadSingle', UploadSingle)
|
||||
Vue.component('UploadMultiple', UploadMultiple)
|
||||
Vue.component('TreeGrid', TreeGrid)
|
||||
Vue.component('AsyncModal', AsyncModal)
|
||||
Vue.component('InfoCard', InfoCard)
|
||||
Vue.component('LoadFlower', LoadFlower)
|
||||
Vue.component('SplitPane', SplitPane)
|
||||
Vue.component('TextArea', TextArea)
|
||||
Vue.component('CommonIcon', CommonIcon)
|
||||
Vue.component('Editor', Editor)
|
||||
Vue.component('editModal', editModal)
|
||||
Vue.component('fieldItem', fieldItem)
|
||||
Vue.component('FieldRenderer', FieldRenderer)
|
||||
}
|
||||
|
||||
// 注册自定义组件的方法
|
||||
export function registerComponents(Vue, components = {}) {
|
||||
Object.keys(components).forEach(name => {
|
||||
Vue.component(name, components[name])
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
Main,
|
||||
ParentView,
|
||||
Tables,
|
||||
UploadSingle,
|
||||
UploadMultiple,
|
||||
TreeGrid,
|
||||
AsyncModal,
|
||||
InfoCard,
|
||||
LoadFlower,
|
||||
SplitPane,
|
||||
TextArea,
|
||||
CommonIcon,
|
||||
Editor,
|
||||
editModal,
|
||||
fieldItem,
|
||||
FieldRenderer,
|
||||
registerGlobalComponents,
|
||||
registerComponents
|
||||
}
|
||||
|
||||
|
||||
20
src/components/switch/index.vue
Normal file
20
src/components/switch/index.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<Switch
|
||||
:value="value"
|
||||
v-bind="$attrs"
|
||||
@on-change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Switch',
|
||||
props: ['value'],
|
||||
methods: {
|
||||
handleChange(checked) {
|
||||
this.$emit('input', checked)
|
||||
this.$emit('change', checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -13,38 +13,14 @@
|
||||
<div :class="col.inLine?'inline-row':'line-row'" :key="col.name" v-if="col.key&&!col.display">
|
||||
<FormItem :label="col.title" :prop="col.key" :rules="curRules[col.key]" :style=" col.rowStyle">
|
||||
<Row>
|
||||
|
||||
<Select class="text-left" filterable v-if="col.com==='Select'" v-model='row[col.key]' v-bind="col" :disabled="getDisabled(col)">
|
||||
<Option :value="item.key" :key="item.key" v-for="item in col.source">{{item.value }}</Option>
|
||||
</Select>
|
||||
|
||||
<RadioGroup v-else-if="col.com==='Radio'" v-model="row[col.key]" v-bind="col" :disabled="getDisabled(col)">
|
||||
<Radio :label="item.key" :key="item.key" v-for="item in col.source">
|
||||
{{item.value}}
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
|
||||
<AutoComplete v-else-if="col.com==='SelectIcon'" icon="ios-search" v-model="row[col.key]" v-bind="col" :disabled="getDisabled(col)">
|
||||
<Option v-for="(icon,index) in icons" :value="icon" :key="index">
|
||||
<Icon size="20" :type="icon" />
|
||||
{{ icon }}
|
||||
</Option>
|
||||
</AutoComplete>
|
||||
|
||||
<UploadSingle v-else-if="col.com==='upload_Img'" v-model="row[col.key]" v-bind="col" :disabled="getDisabled(col)">
|
||||
|
||||
</UploadSingle>
|
||||
|
||||
<TextArea v-else-if="col.com==='TextArea'" v-model="row[col.key]" v-bind="col" :disabled="getDisabled(col)">
|
||||
|
||||
</TextArea>
|
||||
|
||||
<templateRender v-else-if="col.editRender" :value="row[col.key]" :render='col.editRender'></templateRender>
|
||||
|
||||
<Input v-else-if="!col.com" v-model="row[col.key]" v-bind="col" style="width:100%;" :disabled="getDisabled(col)" />
|
||||
|
||||
<component v-else v-bind:is="col.com" v-model="row[col.key]" v-bind="col" :disabled="getDisabled(col)"></component>
|
||||
|
||||
<!-- 使用专门的字段渲染组件 -->
|
||||
<FieldRenderer
|
||||
:col="col"
|
||||
:value="row[col.key]"
|
||||
:disabled="getDisabled(col)"
|
||||
@input="handleFieldInput(col.key, $event)"
|
||||
@change="handleFieldChange(col.key, $event)"
|
||||
/>
|
||||
</Row>
|
||||
</FormItem>
|
||||
</div>
|
||||
@@ -64,21 +40,12 @@
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import templateRender from './templateRender'
|
||||
|
||||
// 导入框架中的图标配置
|
||||
let icons = []
|
||||
try {
|
||||
icons = require('../../config/icons.json') || []
|
||||
} catch (e) {
|
||||
console.warn('未找到图标配置文件,图标选择功能将不可用', e)
|
||||
icons = []
|
||||
}
|
||||
import FieldRenderer from './fieldRenderer'
|
||||
|
||||
export default {
|
||||
props: ['columns', 'width'],
|
||||
components: {
|
||||
templateRender
|
||||
FieldRenderer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -87,7 +54,6 @@ export default {
|
||||
isRefresh: true,
|
||||
isEdit: false,
|
||||
isOPen: false,
|
||||
icons: [],
|
||||
row: {},
|
||||
callback: null
|
||||
}
|
||||
@@ -123,6 +89,16 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理字段输入事件
|
||||
handleFieldInput(key, value) {
|
||||
this.$set(this.row, key, value)
|
||||
},
|
||||
|
||||
// 处理字段变化事件
|
||||
handleFieldChange(key, value) {
|
||||
this.$set(this.row, key, value)
|
||||
},
|
||||
|
||||
// 判断字段是否禁用
|
||||
getDisabled(col) {
|
||||
// 如果是编辑模式且字段设置了disabled,则禁用
|
||||
@@ -192,12 +168,6 @@ export default {
|
||||
this.isOPen = false
|
||||
},
|
||||
async init(row, isgl) {
|
||||
// 安全处理图标数据
|
||||
if (Array.isArray(icons)) {
|
||||
this.icons = icons.map((item) => item.trim ? item.trim() : item)
|
||||
} else {
|
||||
this.icons = []
|
||||
}
|
||||
row = row || {}
|
||||
let rules = this.curRules
|
||||
if (isgl) {
|
||||
|
||||
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