This commit is contained in:
sc 2021-09-28 17:04:03 +08:00
parent f3a99b441d
commit 0ed0867862
6 changed files with 360 additions and 25 deletions

View File

@ -0,0 +1,42 @@
<!--
* @Descripttion: 封装的codemirror
* @version: 1.0
* @Author: sakuya
* @Date: 2021年9月28日15:02:19
* @LastEditors:
* @LastEditTime:
-->
<template>
<div class="sc-code">
<textarea v-html="code" wrap="off" rows="10"></textarea>
</div>
</template>
<script>
export default {
props: {
modelValue: [String, Object, Array],
},
data() {
return {
code: ""
}
},
watch: {
code(val){
this.$emit('update:modelValue', JSON.parse(val));
},
},
mounted() {
this.code = JSON.stringify(this.modelValue, null, 4)
},
methods: {
}
}
</script>
<style scoped>
.sc-code textarea {width: 100%;font-size: 12px;padding:15px;}
</style>

View File

@ -8,18 +8,84 @@
-->
<template>
<el-form ref="form" :model="form" :label-width="config.labelWidth" :label-position="config.labelPosition">
<el-form ref="form" :model="form" :label-width="config.labelWidth || '100px'" :label-position="config.labelPosition">
<el-row :gutter="15">
<template v-for="(item, index) in config.items" :key="index">
<el-col v-if="!hideHandle(item)" :span="item.span || 24">
<template v-for="(item, index) in config.formItems" :key="index">
<el-col :span="item.span || 24" v-if="!hideHandle(item)">
<el-form-item :label="item.label" :prop="item.name" :rules="rulesHandle(item)">
<component :is="`${item.component}-render`" v-model="form" :item="item"></component>
<!-- input -->
<template v-if="item.component=='input'" >
<el-input v-model="form[item.name]" :placeholder="item.options.placeholder" clearable></el-input>
</template>
<!-- checkbox -->
<template v-else-if="item.component=='checkbox'" >
<template v-if="item.name" >
<el-checkbox v-model="form[item.name][_item.name]" :label="_item.label" v-for="(_item, _index) in item.options.items" :key="_index"></el-checkbox>
</template>
<template v-else >
<el-checkbox v-model="form[_item.name]" :label="_item.label" v-for="(_item, _index) in item.options.items" :key="_index"></el-checkbox>
</template>
</template>
<!-- checkboxGroup -->
<template v-else-if="item.component=='checkboxGroup'" >
<el-checkbox-group v-model="form[item.name]">
<el-checkbox v-for="_item in item.options.items" :key="_item.value" :label="_item.value">{{_item.label}}</el-checkbox>
</el-checkbox-group>
</template>
<!-- upload -->
<template v-else-if="item.component=='upload'" >
<el-col v-for="(_item, _index) in item.options.items" :key="_index">
<el-form-item :prop="_item.name">
<sc-upload v-model="form[_item.name]" :title="_item.label"></sc-upload>
</el-form-item>
</el-col>
</template>
<!-- switch -->
<template v-else-if="item.component=='switch'" >
<el-switch v-model="form[item.name]" />
</template>
<!-- select -->
<template v-else-if="item.component=='select'" >
<el-select v-model="form[item.name]" :multiple="item.options.multiple" :placeholder="item.options.placeholder" clearable filterable style="width: 100%;">
<el-option v-for="option in item.options.items" :key="option.value" :label="option.label" :value="option.value"></el-option>
</el-select>
</template>
<!-- date -->
<template v-else-if="item.component=='date'" >
<el-date-picker v-model="form[item.name]" :type="item.options.type" :shortcuts="item.options.shortcuts" :default-time="item.options.defaultTime" :value-format="item.options.valueFormat" :placeholder="item.options.placeholder || '请选择'"></el-date-picker>
</template>
<!-- number -->
<template v-else-if="item.component=='number'" >
<el-input-number v-model="form[item.name]" controls-position="right"></el-input-number>
</template>
<!-- radio -->
<template v-else-if="item.component=='radio'" >
<el-radio-group v-model="form[item.name]">
<el-radio v-for="_item in item.options.items" :key="_item.value" :label="_item.value">{{_item.label}}</el-radio>
</el-radio-group>
</template>
<!-- noComponent -->
<template v-else>
未匹配到相应组件 {{item.component}}
</template>
</el-form-item>
</el-col>
</template>
<!-- <template v-for="(item, index) in config.items" :key="index">
<el-col v-if="!hideHandle(item)" :span="item.span || 24">
<el-form-item v-if="item.name" :label="item.label" :prop="item.name" :rules="rulesHandle(item)">
<component :is="`${item.component}-render`" v-model="form[item.name]" :item="item"></component>
</el-form-item>
<el-form-item v-else :label="item.label" :rules="rulesHandle(item)">
<component v-for="(_item, _index) in item.options.items" :key="_index" :is="`${item.component}-render`" v-model="form[_item.name]" :item="_item"></component>
</el-form-item>
</el-col>
</template> -->
<el-col :span="24">
<el-form-item>
<el-button type="primary">提交</el-button>
<el-button type="primary" @click="submit">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-col>
@ -28,11 +94,15 @@
</template>
<script>
import inputRender from './items/input'
import { defineAsyncComponent } from 'vue';
const inputRender = defineAsyncComponent(() => import('./items/input'));
//import inputRender from './items/input'
import selectRender from './items/select'
import checkboxRender from './items/checkbox'
import checkboxGroupRender from './items/checkboxGroup'
import switchRender from './items/switch'
import uploadRender from './items/upload'
export default {
props: {
@ -44,7 +114,8 @@
selectRender,
checkboxRender,
checkboxGroupRender,
switchRender
switchRender,
uploadRender
},
data() {
return {
@ -56,24 +127,45 @@
this.$emit("update:modelValue", val)
}
},
mounted() {
created() {
this.setForm()
},
mounted() {
},
methods: {
//form
setForm(){
this.config.items.forEach((item) => {
this.config.formItems.forEach((item) => {
if(item.component == 'checkbox'){
if(item.name){
const value = {}
item.options.items.forEach((option) => {
value[option.name] = option.value
})
this.form[item.name] = value
}else{
item.options.items.forEach((option) => {
this.form[option.name] = option.value
})
}
}else if(item.component == 'upload'){
item.options.items.forEach((option) => {
this.form[option.name] = option.value
this.form[option.name] = option.value
})
}else{
this.form[item.name] = item.value
}
})
this.form = Object.assign({}, this.form, this.modelValue)
this.form = this.deepMerge(this.form, this.modelValue)
//this.form = Object.assign({}, this.form, this.modelValue)
},
deepMerge(obj1, obj2) {
let key;
for (key in obj2) {
obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" && (obj2[key] && obj2[key].toString() === "[object Object]") ? this.deepMerge(obj1[key], obj2[key]) : (obj1[key] = obj2[key])
}
return {...obj1};
},
updata(val, item){
console.log(val, item)
@ -92,6 +184,16 @@
requiredRule.required = exp
}
return item.rules
},
submit(){
this.$refs.form.validate((valid) => {
if (valid) {
console.log(this.form)
alert('submit!')
}else{
return false
}
})
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<el-checkbox v-for="option in item.options.items" :key="option.value" v-model="value[option.name]" :label="option.label"></el-checkbox>
<el-checkbox v-model="value" :label="item.label"></el-checkbox>
</template>
<script>

View File

@ -1,5 +1,5 @@
<template>
<el-input v-model="form[item.name]" :placeholder="item.options.placeholder"></el-input>
<el-input v-model="value" :placeholder="item.options.placeholder"></el-input>
</template>
<script>
@ -11,14 +11,14 @@
},
data() {
return {
form: this.modelValue
value: this.modelValue
}
},
watch:{
modelValue(val){
this.form = val
this.value = val
},
form(val){
value(val){
this.$emit("update:modelValue", val)
}
},

View File

@ -0,0 +1,39 @@
<template>
<el-col>
<el-form-item :prop="item.name">
<sc-upload v-model="value" :title="item.label"></sc-upload>
</el-form-item>
</el-col>
</template>
<script>
export default {
name: 'uploadRender',
props: {
modelValue: [String, Number, Boolean, Date, Object, Array],
item: { type: Object, default: () => {} }
},
data() {
return {
value: this.modelValue
}
},
watch:{
modelValue(val){
this.value = val
},
value(val){
this.$emit("update:modelValue", val)
}
},
mounted() {
},
methods: {
}
}
</script>
<style>
</style>

View File

@ -1,8 +1,13 @@
<template>
<el-main>
<el-row :gutter="15">
<el-col :lg="6">
<el-card shadow="never" header="1.参数配置">
<pre>{{config2}}</pre>
</el-card>
</el-col>
<el-col :lg="12">
<el-card shadow="never" header="表单渲染器">
<el-card shadow="never" header="2.渲染器">
<sc-form :config="config2" v-model="data"></sc-form>
</el-card>
<el-card shadow="never" header="" v-if="false">
@ -22,8 +27,8 @@
</el-form>
</el-card>
</el-col>
<el-col :lg="12">
<el-card shadow="never" header="表单渲染器">
<el-col :lg="6">
<el-card shadow="never" header="3.表单输出">
<pre>{{data}}</pre>
</el-card>
</el-col>
@ -32,8 +37,13 @@
</template>
<script>
//import scCode from '@/components/scCode';
export default {
name: 'formRender',
components: {
//scCode
},
data() {
return {
d: {
@ -47,26 +57,80 @@
},
data: {
name: "Activity name",
checkbox: {
option1: true
},
checkboxGroup: ["option1"],
select: ["1"],
select2: "1"
},
config2: {
labelWidth: '130px',
labelPosition: 'right',
size: 'medium',
items: [
formItems: [
{
label: "Activity name",
message: "123",
name: "name",
value: "",
value: "123",
component: "input",
options: {
placeholder: "Activity name",
},
rules: [
{required: true, message: "Please input Activity name", trigger: "blur"}
],
requiredHandle: "$.required==true",
},
{
label: "Select",
name: "select",
value: "",
component: "select",
span: 12,
options: {
multiple: true,
items:[
{
label: "选项1",
value: "1"
},
{
label: "选项2",
value: "2"
}
]
},
rules: [
{required: true, message: "Please input Activity name", trigger: "change"}
],
requiredHandle: "$.required==true",
},
{
label: "Select2",
name: "select2",
value: "",
component: "select",
span: 12,
options: {
items:[
{
label: "选项1",
value: "1"
},
{
label: "选项2",
value: "2"
}
]
}
},
{
label: "Checkbox",
name: "checkbox",
component: "checkbox",
span: 12,
options: {
items:[
{
@ -81,7 +145,95 @@
}
]
}
}
},
{
label: "Checkbox group",
name: "checkboxGroup",
value: [],
component: "checkboxGroup",
span: 12,
options: {
items:[
{
label: "选项1",
value: "option1"
},
{
label: "选项2",
value: "option2"
}
]
}
},
{
label: "Required handle",
name: "required",
value: false,
component: "switch",
},
{
label: "Upload",
component: "upload",
options: {
items:[
{
label: "图像1",
name: "img1",
value: ""
},
{
label: "图像2",
name: "img2",
value: ""
}
]
},
hideHandle: "$.required==true"
},
{
label: "Date",
name: "date",
value: "",
component: "date",
options: {
type: "datetime",
valueFormat: "YYYY-MM-DD HH:mm:ss",
defaultTime: new Date(2000, 1, 1, 12, 0, 0),
shortcuts: [
{
text: '今天',
value: new Date(),
}
]
},
rules: [
{required: true, message: "Please input Data", trigger: "change"}
],
},
{
label: "Number",
name: "number",
value: 0,
component: "number",
},
{
label: "Radio",
name: "radio",
value: "",
component: "radio",
options: {
items:[
{
label: "选项1",
value: "1"
},
{
label: "选项2",
value: "2"
}
]
}
},
]
},
config: {