add scform demo

This commit is contained in:
sc 2021-09-24 17:01:05 +08:00
parent 3b99ab5399
commit f3a99b441d
10 changed files with 549 additions and 0 deletions

View File

@ -0,0 +1,101 @@
<!--
* @Descripttion: 动态表单渲染器
* @version: 1.0
* @Author: sakuya
* @Date: 2021年9月22日09:26:25
* @LastEditors:
* @LastEditTime:
-->
<template>
<el-form ref="form" :model="form" :label-width="config.labelWidth" :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">
<el-form-item :label="item.label" :prop="item.name" :rules="rulesHandle(item)">
<component :is="`${item.component}-render`" v-model="form" :item="item"></component>
</el-form-item>
</el-col>
</template>
<el-col :span="24">
<el-form-item>
<el-button type="primary">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</template>
<script>
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'
export default {
props: {
modelValue: { type: Object, default: () => {} },
config: { type: Object, default: () => {} }
},
components: {
inputRender,
selectRender,
checkboxRender,
checkboxGroupRender,
switchRender
},
data() {
return {
form: {}
}
},
watch:{
form(val){
this.$emit("update:modelValue", val)
}
},
mounted() {
this.setForm()
},
methods: {
//form
setForm(){
this.config.items.forEach((item) => {
if(item.component == 'checkbox'){
item.options.items.forEach((option) => {
this.form[option.name] = option.value
})
}else{
this.form[item.name] = item.value
}
})
this.form = Object.assign({}, this.form, this.modelValue)
},
updata(val, item){
console.log(val, item)
},
hideHandle(item){
if(item.hideHandle){
const exp = eval(item.hideHandle.replace(/\$/g,"this.form"))
return exp
}
return false
},
rulesHandle(item){
if(item.requiredHandle){
const exp = eval(item.requiredHandle.replace(/\$/g,"this.form"))
var requiredRule = item.rules.find(t => 'required' in t)
requiredRule.required = exp
}
return item.rules
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,35 @@
<template>
<el-checkbox v-for="option in item.options.items" :key="option.value" v-model="value[option.name]" :label="option.label"></el-checkbox>
</template>
<script>
export default {
name: 'checkboxGroupRender',
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

@ -0,0 +1,37 @@
<template>
<el-checkbox-group v-model="value">
<el-checkbox v-for="item in item.options.items" :key="item.value" :label="item.value">{{item.label}}</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
name: 'checkboxGroupRender',
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

@ -0,0 +1,35 @@
<template>
<el-input v-model="form[item.name]" :placeholder="item.options.placeholder"></el-input>
</template>
<script>
export default {
name: 'inputRender',
props: {
modelValue: [String, Number, Boolean, Date, Object, Array],
item: { type: Object, default: () => {} }
},
data() {
return {
form: this.modelValue
}
},
watch:{
modelValue(val){
this.form = val
},
form(val){
this.$emit("update:modelValue", val)
}
},
mounted() {
},
methods: {
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,39 @@
<template>
<el-form-item :label="item.label" :rules="item.options.rules">
<el-select v-model="value" :multiple="item.options.multiple" :placeholder="item.options.placeholder" style="width: 100%;">
<el-option v-for="option in item.options.options" :key="option.value" :label="option.label" :value="option.value"></el-option>
</el-select>
</el-form-item>
</template>
<script>
export default {
name: 'selectRender',
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

@ -0,0 +1,36 @@
<template>
<el-switch v-model="value" />
<div v-if="item.message" class="el-form-item-msg">{{item.message}}</div>
</template>
<script>
export default {
name: 'switchRender',
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

@ -21,6 +21,7 @@ import scTableSelect from './components/scTableSelect'
import scPageHeader from './components/scPageHeader'
import scSelect from './components/scSelect'
import scDialog from './components/scDialog'
import scForm from './components/scForm'
import auth from './directives/auth'
import role from './directives/role'
import time from './directives/time'
@ -52,6 +53,7 @@ app.component('scTableSelect', scTableSelect);
app.component('scPageHeader', scPageHeader);
app.component('scSelect', scSelect);
app.component('scDialog', scDialog);
app.component('scForm', scForm);
//注册全局指令
app.directive('auth', auth)

View File

@ -41,6 +41,15 @@ const routes = [{
icon: "el-icon-s-fold",
},
component: () => import(/* webpackChunkName: "tableSetting" */ '@/views/setting/table'),
},
{
name: "formRender",
path: "/vab/form",
meta: {
title: "动态表单",
icon: "el-icon-receiving",
},
component: () => import(/* webpackChunkName: "formRender" */ '@/views/vab/form'),
}
]
}

View File

@ -20,3 +20,5 @@
.header-tabs .el-tabs {border:0;box-shadow:none;}
.header-tabs .el-tabs__content {display: none;}
.header-tabs .el-tabs__item {font-size: 12px;}
.form-title {border-bottom: 1px solid #eee;margin-bottom: 20px;font-size: 17px;padding-bottom: 15px;color: #3c4a54;}

253
src/views/vab/form.vue Normal file
View File

@ -0,0 +1,253 @@
<template>
<el-main>
<el-row :gutter="15">
<el-col :lg="12">
<el-card shadow="never" header="表单渲染器">
<sc-form :config="config2" v-model="data"></sc-form>
</el-card>
<el-card shadow="never" header="" v-if="false">
<el-form ref="formref" :model="d" label-width="100px" label-position="right" :rules="rules">
<h3 class="form-title">基础信息</h3>
<el-form-item label="活动名称" prop="name">
<el-input v-model="d.name"></el-input>
</el-form-item>
<h3 class="form-title">扩展信息</h3>
<el-form-item label="活动名称2" prop="name2">
<el-input v-model="d.name2"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
<el-col :lg="12">
<el-card shadow="never" header="表单渲染器">
<pre>{{data}}</pre>
</el-card>
</el-col>
</el-row>
</el-main>
</template>
<script>
export default {
name: 'formRender',
data() {
return {
d: {
name: "",
name2: ""
},
rules: {
name2: [
{ required: true, message: '请输入活动名称', trigger: 'blur' }
]
},
data: {
name: "Activity name",
},
config2: {
labelWidth: '130px',
labelPosition: 'right',
size: 'medium',
items: [
{
label: "Activity name",
name: "name",
value: "",
component: "input",
options: {
placeholder: "Activity name",
}
},
{
label: "Checkbox",
name: "checkbox",
component: "checkbox",
options: {
items:[
{
label: "选项1",
name: "option1",
value: false
},
{
label: "选项2",
name: "option2",
value: false
}
]
}
}
]
},
config: {
labelWidth: '130px',
labelPosition: 'right',
size: 'medium',
items: [
{
label: "Required handle",
name: "required",
component: "switch",
span: 24,
},
{
label: "Hide handle",
name: "hide",
component: "switch",
span: 24,
},
{
label: "Activity name",
name: "name",
component: "input",
span: 24,
options: {
placeholder: "Activity name",
},
rules: [
{required: true, message: "Please input Activity name", trigger: "blur"}
],
requiredHandle: "$.required==true",
hideHandle: "$.hide==true"
},
{
label: "Checkbox",
name: "checkbox",
component: "checkbox",
span: 24,
options: {
items:[
{
label: "选项1",
value: "option1"
},
{
label: "选项2",
value: "option2"
}
]
}
},
{
label: "Checkbox group",
name: "checkboxGroup",
component: "checkboxGroup",
span: 24,
options: {
items:[
{
label: "选项1",
value: "option1"
},
{
label: "选项2",
value: "option2"
}
]
}
},
// {
// label: "",
// name: "type",
// component: "select",
// span: 12,
// options: {
// defaultValue: "",
// placeholder: "",
// options: [
// {
// label: '',
// value: '1',
// },
// {
// label: '',
// value: '2',
// }
// ],
// rules: [
// {
// required: true,
// message: "",
// trigger: "blur"
// }
// ]
// },
// dynamicHide: "$.switch==true"
// },
// {
// label: "",
// name: "type2",
// component: "select",
// span: 12,
// options: {
// multiple: true,
// defaultValue: "",
// placeholder: "",
// options: [
// {
// label: '',
// value: '1',
// },
// {
// label: '',
// value: '2',
// }
// ],
// rules: [
// {
// required: true,
// message: "",
// trigger: "blur"
// }
// ]
// },
// dynamicHide: "$.switch==true",
// },
// {
// label: "",
// name: "checkbox",
// component: "checkbox",
// span: 12,
// options: {
// items: [
// {
// label: "1",
// value: "1"
// },
// {
// label: "2",
// value: "2"
// }
// ]
// },
// dynamicHide: "$.switch==true"
// }
]
}
}
},
mounted() {
},
methods: {
onSubmit(){
this.$refs.formref.validate((valid, obj) => {
console.log(obj)
if (valid) {
alert('submit!')
}else{
return false
}
})
}
}
}
</script>
<style>
</style>