Schema Form 方案表单
通过配置JSON Schema的方式快速生成一个表单
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">基础用法
schema设置配置项,其中props参数与eagle-form组件参数相同,items则对应eagle-form-item组件,默认参数为<component>组件与eagle-form-item组件参数的并集。
::: snippet 基础示例
<template>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名' },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">表单校验
配置下的props对应eagle-form的参数,可以在此统一配置rules;配置下的items的每一项都对应eagle-form-item,也可以直接配置rules设置该项的校验规则。
::: snippet 设置props下的校验规则示例
<template>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: {
labelWidth: '70px',
size: 'small',
span: 12,
rules: {
name: [{ required: true, message: '请输入姓名' }],
age: [{ required: true, message: '请输入有效年龄' }],
}
},
items: [
{ is: 'el-input', prop: 'name', label: '姓名' },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
};
</script>
:::
::: snippet 设置items下的校验规则示例
<template>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄', rules: [{ required: true, message: '请输入有效年龄' }] },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">表单提交
表单会默认提供一个footer插槽,并提供表单的提交、取消、重置等方法,且相关方法都有对应的事件监听。也可以不使用插槽提供的方法直接自定义。
::: snippet 配置footer插槽提供触发方法的示例
<template>
<eagle-schema-form v-model="form" :schema="schema" @submit="onSubmit" @reset="onReset" @cancel="onCancel">
<template #footer="{ submit, reset, cancel }">
<eagle-form-item>
<el-button type="primary" @click="submit">确定</el-button>
<el-button plain @click="reset">重置</el-button>
<el-button plain @click="cancel">取消</el-button>
</eagle-form-item>
</template>
</eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄', rules: [{ required: true, message: '请输入有效年龄' }] },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
methods: {
onSubmit(value) {
console.log(value);
},
onReset() {
console.log('reset');
},
onCancel() {
console.log('cancal');
}
}
};
</script>
:::
::: snippet 自定义提交的示例
<template>
<eagle-schema-form ref="form" v-model="form" :schema="schema" @submit="onSubmit" @reset="onReset" @cancel="onCancel">
<template #footer>
<eagle-form-item>
<el-button type="primary" @click="onSubmit">确定</el-button>
<el-button plain @click="onReset">重置</el-button>
<el-button plain @click="onCancel">取消</el-button>
</eagle-form-item>
</template>
</eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄', rules: [{ required: true, message: '请输入有效年龄' }] },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
methods: {
onSubmit() {
this.$refs.form.validate(valid => {
if (valid) {
console.log(this.form);
}
});
},
onReset() {
this.$refs.form.resetFields();
},
onCancel() {
console.log('cancal');
}
}
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">显示状态
支持配置if、show对表单项进行v-if、v-show逻辑的设置。
::: snippet 隐藏表单项的示例
<template>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'id', props: { disabled: true }, label: 'ID', show: false },
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄', rules: [{ required: true, message: '请输入有效年龄' }] },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
{ is: 'el-input', prop: 'package', label: '包裹', span: 24, if: false },
]
},
};
},
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">动态规则
某些情况下,表单中的某一项根据另一项的值来做当前项显示状态、校验规则、标签名称的动态判断。支持将任意表单配置项的任意参数改写为function类型,参数提供value、model、onInput等。
::: snippet 动态规则仅在配置项中有效,配置项子节点中无效
<template>
<eagle-schema-form v-model="form" :schema="schema" @submit="onSubmit" @reset="onReset" @cancel="onCancel">
<template #footer="{ submit, reset, cancel }">
<eagle-form-item>
<el-button type="primary" @click="submit">确定</el-button>
<el-button plain @click="reset">重置</el-button>
<el-button plain @click="cancel">取消</el-button>
</eagle-form-item>
</template>
</eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
age: '',
address: '',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄', rules: [{ required: true, message: '请输入有效年龄' }], if({ model }) { return model.name } },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24,
if({ model }) { return model.age },
rules({ model }) {
return model.address ? [{ required: true, min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'input' }] : [{ required: false }];
}
},
]
},
};
},
methods: {
onSubmit(value) {
console.log(value);
},
onReset() {
console.log('reset');
},
onCancel() {
console.log('cancal');
}
}
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">配置复用
因为与eagle-form、eagle-form-item用法相同,所以除了可以用作表单以外,也可用作详情展示,同时因为本身是schema配置项,所以可以做到表单和详情配置复用。
::: snippet 配置复用示例
<template>
<el-row>
<el-col :span="12">
<div style="margin-bottom: 20px">表单</div>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</el-col>
<el-col :span="12">
<div style="margin-bottom: 20px">详情</div>
<eagle-schema-form :value="detail" :schema="detailSchema"></eagle-schema-form>
</el-col>
</el-row>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
detail: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名' },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
]
},
};
},
computed: {
detailSchema() {
const schema = this.schema;
// 去掉所有配置项的is参数即默认以文本展示
return { ...schema, items: schema.items.map(({ is, ...other }) => ({ ...other })) }
}
}
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">自定义插槽
在某些特殊情况下,表单项可能是当前页面的临时组件,或者项目并没有全局引入组件,亦或者需要一些特殊的函数去处理,此时可以使用自定义插槽替换默认配置项。插槽默认提供了value和onInput用于维护当前值。
::: snippet schema配置中items配置项的is设置为slot,即可在组件下通过插槽的方式替换配置项。默认支持具名插槽、label插槽、error插槽,与el-form-item的插槽类似。
<template>
<eagle-schema-form v-model="form" :schema="schema">
<!-- error插槽,作用:修改当前项的校验信息样式 -->
<template #error-name>
<div><span>请输入</span><el-tag size="mini">格式正确</el-tag><span>的姓名</span></div>
</template>
<!-- label插槽,作用:自定义当前项的label -->
<template #label-age>
<el-tooltip content="说明" placement="top" effect="light">
<i class="el-icon-question"></i>
</el-tooltip>
<span>年龄</span>
</template>
<!-- 具名插槽,作用:自定义当前项的值 -->
<template #address="{ value, onInput }">
<div>
<el-link size="mini" type="primary" :underline="false" @click="() => onInput('当前地址xxxxxx')">键入当前地址</el-link>
<el-input type="textarea" :value="value" @input="onInput" />
</div>
</template>
</eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'slot', prop: 'address', label: '住址', span: 24 },
]
},
};
},
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">配置子节点
使用表单时,除了可能会出现单组件子节点以外,可能出现带有子节点的子组件。schema也支持对子节点进行配置。
::: snippet schema配置中items配置项的children可以配置子节点,格式同<component>组件。
<template>
<eagle-schema-form v-model="form" :schema="schema"></eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
packages: ['零食'],
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
{
is: 'el-checkbox-group',
prop: 'packages',
label: '包裹',
children: [
{ is: 'el-checkbox', props: { label: '零食' } },
{ is: 'el-checkbox', props: { label: '手机' } },
{ is: 'el-checkbox', props: { label: '电脑' } },
],
span: 24
},
]
},
};
},
};
</script>
:::
6a3e9fa03a9e62888fd3096196dcc68e3e3bb90a/examples/views/docs/component/schema-form.md#">复杂表单
一般情况下,复杂表单建议使用eagle-form、eagle-form-item等组件构建视图,不建议使用schema的方式配置。但是利用schema配置项的一些特性,也可以做到部分复杂表单使用schema配置完成。
::: snippet 包含了插槽、子节点、自定义子节点的复杂示例
<template>
<eagle-schema-form v-model="form" :schema="schema" @submit="onSubmit" @cancel="onCancel">
<template #error-name>
<div><span>请输入</span><el-tag size="mini">格式正确</el-tag><span>的姓名</span></div>
</template>
<template #label-packages>
<el-tooltip content="详情" placement="top" effect="light">
<i class="el-icon-question"></i>
</el-tooltip>
<span>包裹</span>
</template>
</eagle-schema-form>
</template>
<script>
export default {
data() {
return {
form: {
name: '张三',
age: 27,
address: '上海市青浦区华新镇纪鹤公路1988号',
packages: ['零食'],
info: {
mobile: '18888888888',
},
admin: 'false',
},
schema: {
props: { labelWidth: '70px', size: 'small', span: 12 },
items: [
{ is: 'el-input', prop: 'name', label: '姓名', rules: [{ required: true, message: '请输入姓名' }] },
{ is: 'el-input-number', prop: 'age', label: '年龄' },
{ is: 'el-input', prop: 'info.mobile', label: '电话' },
{ is: 'el-divider', props: { 'content-position': 'left' }, children: '收货信息', span: 24, labelWidth: '0px' },
{ is: 'el-input', props: { type: 'textarea' }, prop: 'address', label: '住址', span: 24 },
{
is: 'el-checkbox-group',
prop: 'packages',
label: '包裹',
children: [
{ is: 'el-checkbox', props: { label: '零食' } },
{ is: 'el-checkbox', props: { label: '手机' } },
{ is: 'el-checkbox', props: { label: '电脑' } },
],
},
{
is: 'el-select',
prop: 'admin',
label: '管理员',
children: [
{
is: 'el-option',
props: { label: '是', value: 'true' },
children: [
{
is: 'div',
attrs: { style: 'display: flex; align-items: center; justify-content: space-between' },
children: [
{ is: 'span', children: '是' },
{ is: 'el-tag', props: { size: 'mini', type: 'success' }, children: 'yes' },
]
},
]
},
{
is: 'el-option',
props: { label: '否', value: 'false' },
children: [
{
is: 'div',
attrs: { style: 'display: flex; align-items: center; justify-content: space-between' },
children: [
{ is: 'span', children: '否' },
{ is: 'el-tag', props: { size: 'mini', type: 'warning' }, children: 'no' },
]
},
]
},
],
},
]
},
};
},
methods: {
onSubmit(value) {
console.log(value);
},
onCancel() {
console.log('cancal');
}
}
};
</script>
:::
API
Attribute 属性
参数|说明|类型|可选值|默认值 -|-|-|-|- value | 值 | Object | - | {} schema | JSON Schema配置项列表 | Object | - | {}
Events 事件
事件名称|说明|回调参数 -|-|- input | 表单值变化 | model