add scform demo
This commit is contained in:
parent
3b99ab5399
commit
f3a99b441d
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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)
|
||||
|
|
|
@ -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'),
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue