JSON生成表单
表单基础组件集合
<template>
<div class="container">
<div class="form-section">
<div class="form-container">
<XForm
v-if="show"
:config="config"
v-model:api="api"
v-model:formData="formData"
:option="option"
/>
<div>
{{ validateState }}
</div>
</div>
</div>
<div class="data-section">
<CodeView :code="formData" />
</div>
</div>
</template>
<script lang="ts" setup>
import type { formConfigTypes, formOptionsTypes } from "sc-business-ui";
import { ref, nextTick } from "vue";
import CodeView from "./CodeView/index.vue";
// 表单数据
const formData = ref({
name: "s",
autoComplete: "",
activeKey: "0",
testSwitch: false,
cascader: ["1", "1-1"],
transfer: ["1"],
subItem: { name: "123" },
filesId:'123'
});
const validateState = ref("");
const api = ref(null);
const option = ref<formOptionsTypes>({
onSubmit(validate, formData) {
console.log(validate);
validateState.value = validate ? "提交中" : "验证失败";
if (validate) {
api.value.btn.loading(true);
setTimeout(() => {
api.value.btn.loading(false);
validateState.value = "验证成功";
}, 2000);
}
},
created() {
console.log("开始渲染 JSONVIEW");
},
mounted() {
console.log("结束渲染 JSONVIEW");
},
wrap: {
required: false,
colon: true,
},
submitBtn: {
loading: false,
show: true,
click: () => console.log("点击了提交按钮"),
innerText: "sss",
},
resetBtn: { click: () => console.log("点击了重置按钮") },
});
let config: formConfigTypes[] = [
{
field: "name",
type: "formItem",
key: "input",
col: {
span: 12,
},
props: {
self: { placeholder: "名字" },
formItem: {
label: "名字",
rules: [{ required: true, message: "请输入名字", trigger: "blur" }],
},
},
},
{
field: "age",
type: "formItem",
key: "input",
col: {
span: 12,
},
props: {
self: { placeholder: "年龄", type: "number" },
formItem: { label: "年龄", required: false },
},
},
{
field: "area",
type: "formItem",
key: "textarea",
props: {
self: { placeholder: "请输入签名", type: "number" },
formItem: { label: "签名", required: false },
},
},
{
field: "password",
type: "formItem",
key: "password",
props: {
self: { placeholder: "请输入密码", visibilityToggle: true },
formItem: { label: "密码", required: false },
},
},
{
field: "search",
type: "formItem",
key: "search",
props: {
self: { placeholder: "" },
formItem: { label: "搜索", required: false },
},
},
{
key: "radio",
type: "formItem",
field: "radio",
options: [
{ label: "北京", value: 1 },
{ label: "重庆", value: 2 },
],
props: {
self: {},
formItem: {
label: "选择城市",
rules: [{ required: true, message: "请选择城市", trigger: "change" }],
},
},
},
{
key: "checkbox",
type: "formItem",
field: "like",
options: [
{ label: "足球", value: "1" },
{ label: "乒乓球", value: "2" },
{ label: "篮球", value: "3" },
],
props: {
self: {
showCheckAll: true,
},
formItem: { label: "喜好" },
},
},
{
key: "rate",
type: "formItem",
field: "rate",
props: { formItem: { label: "评分" } },
},
{
key: "slider",
type: "formItem",
field: "slider",
props: {
formItem: { label: "滑块" },
self: {
step: 10,
max: 100,
marks: {
0: "0°C",
26: "26°C",
47: "47°C",
100: { style: { color: "#f50" }, label: "100°C" },
},
},
},
},
{
key: "inputNumber",
type: "formItem",
field: "inputNumber",
props: {
formItem: {
label: "输入内容",
rules: [{ required: true, message: "请输入数字", trigger: "blur" }],
},
self: { prefix: "$" },
},
},
{
key: "select",
type: "formItem",
field: "food",
optionsTo: "options",
options: [
{ value: 1, label: "苹果" },
{ value: 4, label: "香蕉" },
],
props: {
formItem: {
label: "食物",
rules: [{ required: true, message: "请选择食物", trigger: "change" }],
},
self: {},
},
},
{
key: "timePicker",
type: "formItem",
field: "timeList",
props: {
formItem: { label: "选择区间时间" },
self: { type: "range" },
},
},
{
key: "switch",
type: "formItem",
field: "testSwitch",
props: {
formItem: { label: "测试 switch" },
self: {
checkedChildren: "开",
unCheckedChildren: "关",
size: "large",
},
},
},
{
key: "autoComplete",
type: "formItem",
field: "autoComplete",
options: [
{ label: "苹果", value: "苹果" },
{ value: "香蕉", label: "香蕉" },
],
props: {
formItem: {
label: "食物",
rules: [{ required: true, message: "请选择食物", trigger: "change" }],
},
self: {},
},
},
{
key: "cascader",
type: "formItem",
field: "cascader",
options: [
{
label: "苹果",
value: "1",
children: [
{ label: "红富士", value: "1-1" },
{ label: "青苹果", value: "1-2", disabled: true },
],
},
{ label: "香蕉", value: "2" },
],
props: {
formItem: {
label: "水果",
rules: [{ required: true, message: "请选择水果", trigger: "change" }],
},
self: {},
},
},
{
key: "transfer",
type: "formItem",
field: "transfer",
options: [
{ key: "1", title: "香蕉", description: "1", disabled: false },
{ key: "2", title: "葡萄", description: "2", disabled: false },
{ key: "3", title: "梨", description: "3", disabled: false },
],
props: {
formItem: { label: "水果" },
self: {},
},
},
{
key:"upload",
type:"formItem",
field:"filesId",
props:{
formItem:{label:"上传文件"},
self:{}
}
}
];
const show = ref(true);
const updateConfig = (e) => {
config = e;
show.value = false;
nextTick(() => {
show.value = true;
});
};
defineExpose({ config, updateConfig });
</script>
<style scoped>
.container {
display: flex;
padding: 0 20px;
box-sizing: border-box;
min-width: 600px;
}
.form-section {
flex: 1;
margin-right: 20px;
}
.form-container {
padding: 20px;
border-radius: 10px;
height: 600px;
overflow: auto;
background-color: #f9f9f9;
}
.data-section {
flex: 1;
}
h2 {
font-weight: 700;
margin-bottom: 10px;
}
.input-wrapper {
display: flex;
align-items: center;
margin-top: 10px;
}
.input-wrapper span {
white-space: nowrap;
margin-right: 10px;
}
a-input {
flex: 1;
}
</style>