介绍

v-formly-v3 是 vue 的动态(JSON 驱动)表单库。它通过JSON Schemaopen in new windowAjv Validatoropen in new window结合生成复杂的动态表单及校验,快速、简洁、高效。通过使用 v-formly-v3 及对应的组件库即可快速构造一个 Form 表单,目前支持 Vue 3.x,组件库支持antdv v3open in new windowelement-plusopen in new window,Vue 3.x 的其他 UI 库(DevUI 等)支持正在开发中。

v-formly-v3 内置封装了 15+ 的组件,同时 v-formly-v3 也支持自定义封装组件,从而可以让你轻松构建复杂的动态表单。

一个简单示例

一个简单的 v-formly-v3 示例,请打开控制台查看表单提交结果

<template>
  <div>
    <v-formly-v3 ref="form" v-model="data" :meta="meta"> </v-formly-v3>
    <div class="btns">
      <a-button type="danger" @click="clear"> 重置 </a-button>
      <a-button type="primary" @click="submit"> 提交 </a-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, toRaw, unref } from "vue";

const form = ref(null);
const meta = {
  type: "object",
  properties: {
    name: {
      title: "姓名",
      type: "string",
      default: "kevin",
      readOnly: false,
      ui: {
        showRequired: true,
        errors: {
          required: "请输入姓名",
        },
        change: (val: string) => console.log("val", val),
      },
    },
    desc: {
      title: "描述",
      type: "string",
      default: "Base on technical, but not limited on it!",
    },
    enable: {
      title: "启用",
      type: "boolean",
      default: true,
    },
  },
  required: ["name"],
};

let data: any = ref({});

function clear() {
  data.value = null;
}

async function submit() {
  let valid = await (form.value as any).validate();
  if (valid) {
    console.log(toRaw(unref(data)));
  }
}
</script>
复制

针对上述示例我们做以下几点解释

  1. v-formly-v3 支持 v-model 双向绑定,可通过修改 data 来随时改变 form 表单数据;

  2. 传入的 schema 是JSON-Schema结构 + 嵌套ui的组合,v-formly 使用 schema 来解析并渲染表单页面;

  3. 以上表单包括两个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,更多内容请查看组件open in new window

快速开始

我们通过创建一个简单的示例项目来告诉大家如何使用 v-formly-v3。

创建一个项目

使用命令行进行初始化。

# npm 6.x
npm create vite@latest hello-formly --template vue-ts

# npm 7+, extra double-dash is needed:
npm create vite@latest hello-formly -- --template vue-ts

# yarn
yarn create vite hello-formly --template vue-ts

# pnpm
pnpm create vite hello-formly --template vue-ts

安装:组件库二选一,使用哪个安装哪个。

安装 ant-design-vue 3.x

$ npm i --save ant-design-vue

$ npm i --save @ant-design/icons-vue

安装 element-plus

$ npm i --save element-plus

$ npm i --save @element-plus/icons-vue

安装 v-formly-v3

使用 yarn 安装yarn add v-formly-v3或者使用 npm 安装npm i v-formly-v3 --save,然后在你的main.ts入口文件添加如下内容:

对于使用 ant-design-vue 3.x 组件库

import { createApp } from "vue";
import App from "./App.vue";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
import * as antIcons from "@ant-design/icons-vue";
import VFormly from "v-formly-v3/antdv";

const app = createApp(App);
app.use(Antd);
Object.keys(antIcons).forEach((key) => {
  app.component(key, (antIcons as any)[key]);
});
app.config.globalProperties.$antIcons = antIcons;

app.use(VFormly, {
  ui: {
    errors: {
      required: "必填项",
    },
  },
});
app.mount("#app");

对于使用 element-plus 组件库

import { createApp } from "vue";
import App from "./App.vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import * as elIcons from "@element-plus/icons-vue";
import VFormly from "v-formly-v3/element";

const app = createApp(App);
app.use(ElementPlus);
for (const [key, component] of Object.entries(elIcons)) {
  app.component(key, component);
}
app.config.globalProperties.$elIcons = elIcons;

app.use(VFormly, {
  lib: "element",
  ui: {
    errors: {
      required: "必填项",
    },
  },
});
app.mount("#app");

使用 v-formly-v3 创建表单

打开App.vue文件,删除里面的内容,复制下面的代码进去并保存。

<template>
  <div class="wrapper">
    <v-formly-v3 ref="form" v-model="data" :meta="meta"> </v-formly-v3>
    <div class="btns">
      <a-button type="danger" @click="clear"> 重置 </a-button>
      <a-button type="primary" @click="submit"> 提交 </a-button>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, toRaw, unref } from "vue";

const form = ref(null);
const meta = {
  type: "object",
  properties: {
    name: {
      title: "姓名",
      type: "string",
      default: "kevin",
      readOnly: false,
      ui: {
        showRequired: true,
        errors: {
          required: "请输入姓名",
        },
        change: (val: string) => console.log("val", val),
      },
    },
    desc: {
      title: "描述",
      type: "string",
      default: "Base on technical, but not limited on it!",
    },
    enable: {
      title: "启用",
      type: "boolean",
      default: true,
    },
  },
  required: ["name"],
};

let data: any = ref({});

function clear() {
  data.value = null;
}

async function submit() {
  let valid = await (form.value as any).validate();
  if (valid) {
    console.log(toRaw(unref(data)));
  }
}
</script>

<style>
.wrapper {
  margin: auto;
  max-width: 600px;
  margin-top: 100px;
}
.btns {
  display: flex;
  justify-content: flex-end;
}
.ant-btn + .ant-btn {
  margin-left: 8px;
}
</style>

此时,你已经完成了一个简单的使用 v-formly-v3 的项目了,这时运行yarn dev或者npm run dev,浏览器中打开http://localhost:5173/open in new window会看到一个简单的表单如下所示: image.png 打开控制台,点击“提交”按钮,你会看到提交的表单数据,非常简单!(PS:如果此时没有看到这个页面,请参考在线示例open in new window查找问题)

参考

v-formly-v3 参考了以下文章及三方库

  1. Create a Vue.js component libraryopen in new window

  2. 基于 Angular 的动态表单库@delon/formopen in new window

  3. antdv v3open in new window

  4. element-plusopen in new window