写在前面
v-formly是vue的动态(JSON驱动)表单库。通过JSON的形式生成表单模板,一份表单简单修改即可多处复用!使您能够快速开发表单页面,相比编写传统的html form表单,使用JSON形式定义表单能够极大的提高了开发效率。目前支持Vue 2.x & Ant Design of Vue v1。
支持的功能
以下列出了v-formly的主要功能点,其他细节请参考文档。
- 支持使用JSON定义表单结构;
- 支持
v-model 双向绑定; - 支持水平、垂直和行内三种布局;
- 支持Ajv内置的校验以及自定义数据校验(同步校验和异步校验);
- 支持自定义表单提交按钮以及内置提交按钮;
- 支持内置的15+组件以及自定义组件;
- 支持表单项
visibleIf 属性动态设置是否可见; - 支持获取表单项
context 并在运行时设置属性;
一个简单的示例
我们通过创建一个简单的示例项目来告诉大家如何使用v-formly。
安装脚手架工具(已安装可忽略)
$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli
创建一个项目
使用命令行进行初始化。
$ vue create antd-demo
并配置项目。
若安装缓慢报错,可尝试用 cnpm 或别的镜像源自行安装:rm -rf node_modules && cnpm install 。
安装ant-design-vue 1.x
$ npm i --save ant-design-vue@1.7.8
安装v-formly
使用yarn安装yarn add v-formly 或者使用npm安装npm i v-formly --save ,然后在你的main.js 入口文件添加如下内容:
import Vue from 'vue';
import App from './App';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
import VFormly from "v-formly";
Vue.config.productionTip = false
Vue.use(Antd);
Vue.use(VFormly);
new Vue({
render: h => h(App),
}).$mount('#app')
使用v-formly创建表单
打开App.vue 文件,删除里面的内容,复制下面的代码进去并保存。
<template>
<div id="app">
<div class="wrapper">
<v-formly ref="form" v-model="data" :meta="meta"> </v-formly>
<div class="btns">
<a-button type="danger" @click="clear"> 重置 </a-button>
<a-button type="primary" @click="submit"> 提交 </a-button>
</div>
</div>
</div>
</template>
<script>
export default {
name: "App",
data: function () {
return {
meta: {
type: "object",
properties: {
name: {
title: "姓名",
type: "string",
default: "kevin",
ui: {
showRequired: true,
},
},
desc: {
title: "描述",
type: "string",
default: "Base on technical, but not limited on it!",
ui: {
change: (val) => {
console.log("val = ", val);
},
},
},
enable: {
title: "启用",
type: "boolean",
},
},
required: ["name"],
},
data: { enable: true },
};
},
methods: {
clear() {
this.data = null;
},
async submit() {
let valid = await this.$refs.form.validate();
if (valid) {
this.$message.success(JSON.stringify(this.data));
}
},
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
margin-top: 60px;
}
.wrapper {
margin: auto;
max-width: 600px;
}
.btns {
display: flex;
justify-content: flex-end;
}
.ant-btn + .ant-btn {
margin-left: 8px;
}
</style>
此时,你已经完成了一个简单的使用v-formly的项目了,这是运行yarn serve 或者npm run serve ,浏览器中会看到一个简单的表单如下所示:
打开控制台,点击“提交”按钮,你会看到提交的表单数据,非常简单!(PS:如果此时没有看到这个页面,请参考在线示例查找问题)
针对上述示例我们做以下几点解释:
-
v-formly 支持 v-model 双向绑定,可通过修改 data 来随时改变 form 表单数据; -
传入的 meta 是JSON-Schema 结构 + 嵌套ui 的组合,v-formly 使用 meta 来解析并渲染表单页面; -
以上表单包括两个string 类型和一个boolean 类型的内置component . a. 其中name 为必填项(required: ["name"] 体现出来),且默认内容为“kevin”,其中ui.showRequired 为 true 会添加 label 前面的红色星号; b. desc 非必填,默认内容为“Base on technical, but not limited on it!”,且提供了 change 事件,当输入改变时触发; c. enable 为一个简单的 AntDv 的Switch 组件。
通过上述简单的表单示例,我们大概了解了如何开始使用 v-formly,接下来我们介绍一下v-formly实现的主要功能点。
支持使用JSON定义表单结构
v-formly正是使用了JSON来定义表单结构才达到了不用画UI的效果,使你在快速创建完表单之后可以快速编写业务逻辑。举例说明,我们的表单需要一个输入框来输入姓名,则定义如下meta 传入v-formly 即可。
{
"type": "object",
"properties": {
"name": {
"title": "姓名",
"type": "string",
"default": "kevin",
"ui": {
"showRequired": true
}
}
},
"required": [
"name"
]
}
此时生成界面如下: 上面的JSON结构定义了label为“姓名”的string 类型的输入框,并且是必填的,默认内容为“kevin”,其中required 为Ajv可识别的内置校验,此时删除输入框中的内容点击提交,则会校验不通过。ui 为v-formly中的自定义节点,非JSON Schema的标准节点,此节点下面几乎同步了ant design vue组件的所有属性,部分不同可参考组件,showRequired 会在label前面添加一个红色的* 号代表必填,无校验逻辑。
此时如果我们在ui 下面增加一个ant design vue组件的属性prefix 如下,
{
"type": "object",
"properties": {
"name": {
"title": "姓名",
"type": "string",
"default": "kevin",
"ui": {
"showRequired": true,
"prefix": "$"
}
}
},
"required": [
"name"
]
}
则生成如下页面:
看到了吗,非常简单!
支持水平、垂直和行内三种布局
v-formly支持这三种布局,可以很好的满足大部分业务需求,水平和垂直的布局适合创建表单或者编辑表单,行内布局适合列表页查询表单等。
我们通过传入layout 来实现各种布局(layout = horizontal | vertical | inline )。
这个非常直观就不多介绍了,可参考布局示例。
支持Ajv内置的校验以及自定义数据校验(同步校验和异步校验)
Ajv内置的校验请参考属性说明,这里分类列出了各种类型的校验属性。
自定义校验我们支持同步校验和异步校验。
- 同步校验
如下meta 结构中,我们在ui 节点下增加了validator 属性,此属性接收一个函数,参数为当前表单项的值,并返回一个错误消息数组,数组中的keyword 为Ajv的标准关键字,这样我们就能够知道是什么错误,message 为自定义错误消息(此处,当val不存在时会报错)。
meta: {
type: "object",
properties: {
name: {
title: "姓名",
type: "string",
default: "kevin",
ui: {
showRequired: true,
validator: (val) => !val ? [{ keyword: "required", message: "Required name" }] : [],
},
},
},
required: ["name"],
},
- 异步校验
异步校验类似,只不过返回的是一个Promise 。
meta: {
type: "object",
properties: {
asyncError: {
title: "异步错误(2秒)",
type: "string",
ui: {
showRequired: true,
validatorAsync: (val) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(
!val ? [{ keyword: "required", message: "Required asyncError",}] : []
);
}, 2000);
});
},
},
},
},
required: ["asyncError"],
},
如需更多了解,请参考文档自定义校验。
支持自定义表单提交按钮以及内置提交按钮
v-formly可以在外部自定义提交按钮,也可以使用v-formly 的内置按钮,使用内置按钮则必须实现重置和提交事件。具体内容请参考表单。
支持表单项visibleIf 属性动态设置是否可见
在表单中会经常出现当某个表单项的值发生改变时,另一个表单项隐藏或出现的逻辑,这里我们就可以使用visibleIf 属性。
{
type: "object",
properties: {
string1: {
title: "字段二是否可见",
type: "string",
ui: {
showRequired: true,
placeholder: "当值为v-formly时字段二可见",
errors: {
required: "请输入",
},
change: (val) => console.log(val),
},
},
string2: {
title: "字段二",
type: "string",
ui: {
showRequired: true,
show: false,
visibleIf: {
"/string1": (context, id, val) => {
return val === "v-formly";
},
},
},
},
},
required: ["string1", "string2"],
}
此案例中,只有第一个输入框的值为“v-formly”的时候,第二个输入框才会出现。
支持获取表单项context 并在运行时设置属性
v-formly还支持运行时动态获取context ,从而可以动态修改表单项的各种参数属性等。
const context = this.$refs.form.getContext("/multiple");
if (context) {
context.ui.options = ["上", "右", "下", "左"];
context.value = "下";
}
详情请参考Radio 单选框“设置规格”按钮示例。
好了,到了这里大家对v-formly都有了一个大概的了解,大家可以自己使用一下v-formly库,也希望大家能够提出宝贵的意见和建议,帮助我更好维护和优化v-formly!
再一次:github地址在这里,文档在这里!觉得对你有帮助就给个star吧!
PS: vue 3 & ant design vue 3.x 正在开发中,Comming soon!
PS: v-formly的英文文档目前缺失中,如果有兴趣可以提PR哦!
|