v-formly-v3 - Vue 3的支持来了,不用画UI就可以构建create/edit页面的库

1,134 阅读4分钟

写在前面

v-formly-v3是Vue 3的动态(JSON驱动)表单库。通过JSON的形式生成表单模板,一份表单简单修改即可多处复用!使您能够快速开发表单页面,相比编写传统的html form表单,使用JSON形式定义表单能够极大的提高了开发效率。目前支持Vue 3.x,组件库支持Ant Design of Vue v3和Element Plus

支持的功能

以下列出了v-formly-v3的主要功能点,其他细节请参考文档

  1. 支持使用JSON定义表单结构;
  2. 支持v-model双向绑定;
  3. 支持水平垂直行内三种布局;
  4. 支持Ajv内置的校验以及自定义数据校验(同步校验和异步校验);
  5. 支持自定义表单提交按钮以及内置提交按钮;
  6. 支持内置的15+组件以及自定义组件;
  7. 支持表单项visibleIf属性动态设置是否可见;
  8. 支持获取表单项context并在运行时设置属性(不推荐);
  9. 支持响应式(区别于Vue 2版本的v-formly使用context运行时设置表单项属性)

一个简单的示例

我们通过创建一个简单的示例项目来告诉大家如何使用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 (这里选择安装antdv,element-plus是一样的)

$ npm i --save ant-design-vue

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

安装v-formly-v3

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

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");

使用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/会看到一个简单的表单如下所示: image.png 打开控制台,点击“提交”按钮,你会看到提交的表单数据,非常简单!(PS:如果此时没有看到这个页面,请参考在线示例查找问题)

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

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

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

  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-v3。

v-formly-v3 如何使用几乎和v-formly一样,所以这里我只简单介绍一下响应式的支持,其他功能点参考文档

支持响应式(区别于Vue 2版本的v-formly使用context运行时设置表单项属性)

v-formly-v3 因为 Vue 3 的响应式,所以也支持响应式的在运行时设置表单项的所有属性。

代码演示

<template>
  <div>
    <v-formly-v3 ref="form" v-model="formData" :meta="meta"></v-formly-v3>
    <div class="btns">
      <a-button type="primary" @click="submit"> 设置边框 </a-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import type VFormly from "@/Formly.vue";

const form = ref<null | InstanceType<typeof VFormly>>(null);
const hasBorder = ref(true);
const meta = {
  type: "object",
  properties: {
    string1: {
      title: "基本使用",
      type: "string",
      ui: {
        showRequired: true,
        placeholder: "Basic usage",
        bordered: hasBorder,
        errors: {
          required: "请输入",
        },
        change: (val: string) => console.log(val),
      },
    },
  },
  required: ["string1"],
};
let formData: any = ref({});

function submit() {
  hasBorder.value = !hasBorder.value;
}
</script>

image.png

我们给输入框设置一个响应式的边框属性const hasBorder = ref(true);,当我们点击“设置边框”按钮时,他会 toggle 边框设置,这样我们就无需像 Vue 2 版本中的v-formly一样获取context上下文,然后通过使用上下文context来设置了,是不是很方便?

最后

好了,到了这里大家对v-formly-v3都有了一个大概的了解,大家可以自己使用一下,也希望大家能够提出宝贵的意见和建议,帮助我更好维护和优化!

再一次:github地址在这里文档在这里!觉得对你有帮助就给个star吧!

PS: v-formly-v3的英文文档目前缺失中,如果有兴趣可以提PR哦!