npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ant-base-form-perfect

v1.0.1

Published

基于Ant组件库的更加完善的表单封装,将不再仅限于操作ref

Downloads

126

Readme

原版为ant-base-form,由于他主要是操作ref来进行数据传递,这版对其优化,不再靠操作组件去操作数据,由于为了不对之前的版本造成影响,新开一个包,为后续bug修复,之前版本ant-base-form不再更新

表单属性

| 属性名 | 解释 | | ----------- | -------------------------------------------------------------------------------------------------------------------- | | fields | 规定你需要生成表单的值结构 | | formLayout | 表单布局 | | defaultSpan | 你的表单默认占用宽度 | | ref | 获取表单的ref,用于提交按钮 | | formData | 初始值,数据改变,formData自动改变并传递回去,此时的提交回显,修改数据都可以在这里面进行 v-model:formData="formData" | | formRules | 自定义校验表单 |

fields属性配置

fields是一个数组对象结构

通用

| 属性名 | 解释 | 类型 | | -------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------- | | name | 绑定的数据名 | string | | label | 左侧名称 | string | | type | 数据类型 | string | | required | 星星,只起到展示左右(主要是为插槽校验考虑) | boolean | | errorMessage | 必填错误信息 | string | | requiredFlag | 确定是否为必填项 | boolean | | componentProps | ant组件本身自带的属性 | Object | | span | 表单占用宽度,取值这个即不会取值默认 | number | | slot | 插槽 | boolean | | dependency | 根据前面的表单选中的内容而决定是否展示 | { dependsOn: "根据那个表单的类型,绑定他的值", value: "当前面绑定的值为某个时,显示这个表单的值",} | | slotFlag | 不使用表单a-form-item的插槽 | true则不使用 | | placeholder | 文本 | 有默认文本,不加则使用默认文本 |

type类型

| Type类型 默认是input | 原生 | 解释 | 数据格式 | | -------------------- | -------------- | ------------------------------------------------------------------------------------------------ | -------- | | input | a-input | 输入框 | | | input-number | a-input-number | 数字输入框 | | | select | a-select | 下拉框 | | | radio | a-radio | 单选 | | | checkbox | a-checkbox | 多选 | | | cascader | a-cascader | 级联 | [{}] | | date | a-date | 日期 | | | switch | a-switch | 开关 | | | time | a-time | 时间 | HH:mm:ss | | textarea | a-textarea | 文本域 | | | imgUpload | a-upload | 原本的上传包括了图片上传以及文件上传,html结构和样式无法统一,因此建议使用插槽去做,不要使用组件 | | | treeSelect | a-tree-select | tree的下拉 | |

以下是需要注意的点

time类型注意点

time类型需要下载ant datajs,并且需要导入且按照他的定义格式,我个人觉得太麻烦了,通过绑定value-format="HH:mm:ss"这个值去定义会好很多,例如

  {
        name: "time",
        label: "时间",
        type: "time",
        componentProps: { "value-format": "HH:mm:ss" },
    },

cascader注意点

在使用级联选择器时,当父亲的宽度低于子孙原生宽度时,报错ResizeObserver loop limit exceeded ,由于他是由递归写成的,结构的改变会导致他的不断的回流,直到报错。

解决办法:

在给他赋值初始值为 cascader: [{}],亦或者忽略

select注意点

在我们使用select组件时,一般需要会需要自定义label,value,options字段,这这里面如何处理?直接使用ant的属性即可

 componentProps: {
            "field-names": { label: "name", value: "id", options: "children" }
        }

cascader,treeSelect组件同理(使用名fieldNames)

checkbox与radio

checkbox有时会包住a-checkbox使用,由于代码底层使用的动态组件,我并未对其封装,如果需要用,请使用插槽,平常用法:

componentProps: {
  options: [数据]
}

radio同理

required&errorMessage&requiredFlag解释

这两个属性是相辅相成的,需要同时进行,required并非真正的进行校验。而是只是有个必选的星号在那里,处理逻辑并未沿用ant组件内部校验,而是通过自己的业务逻辑去判断并产生消息提示

requiredFlag需定义才能开启校验,required只是星号,主要是为了插槽的表单做校验

errorMessage不是必须的,底层做了保底,如果不传,则会采用默认信息提示

插槽表单如何校验?

1.插槽表单无需定义required&errorMessage,只需要required,让他把星号展示出来。

2.在提交按钮校验后去判断他这个值并进行校验

示例:

baseForm.value.handleSubmit((formData: Record<string, any>) => {
    if (!baseForm.value.formData.memberProjectCategoryId) {
          message.error("项目分类不能为空");
              return;
    }
   // 调用接口
    });
});

componentProps

componentProps可以说是最重要的,打个比方,我写一个文本域,即备注表单,我们需要如何定义fields配置。

const fields = ref([
    name:'remark',            // 绑定值
    label:'备注',              // 左侧标题
    type:'textarea',          // 表单类型
    required:true,            // 是否校验
    errorMessage:'请填写备注'   // 校验信息
])

这样,一条表单就配置好了。但是此时你想要把文本域展示默认值,同时控制在2-4行,同时限制他的字数,并显示剩余字数,如何处理?使用componentProps这个属性,继上面的代码继续

const fields = ref([
    name:'remark',            // 绑定值
    label:'备注',              // 左侧标题
    type:'textarea',          // 表单类型
    required:true,            // 是否校验
    errorMessage:'请填写备注',   // 校验信息
    componentProps:{
         "auto-size": { minRows: 2, maxRows: 4 },   // 控制在2-4行
          maxlength: 10,                            // 最大字数
          "show-count": true                        // 展示剩余数字
    }
    placeholder:'文本'
])

注意:对象的键,原本就是字符串,因此我们对于带 - 的属性把他写成字符串即可

这样就ok了,componentProps中的属性均来自ant组件,想要加什么效果加好了即可。

span属性

共24份,设置了span这个值,将替代默认defaultSpan

slot属性

slot即插槽,他的值为布尔值,true为开启插槽,反正不开启,如何使用?

比如你想要在某条表单后面写入插槽,只需要在fields将他定义在那条数据的后面即可,例如:

第一步 定义

const fields: Field[] = [
    {
        name: "username",
        label: "Username",
        type: "input",
        errorMessage: "请输入姓名",
        required: true,
        span: 12,
    },
    {
        name: "sex",
        label: "性别",
        type: "input",
        errorMessage: "请输入性别",
        required: true,
        slot: true,
        span: "12",
    }
];

以上示例即把性别插入姓名后方,如果需要插入到他的前面,即需要把数据放在他的前面即可

第二步 使用

<CustomForm
  ref="customForm"
  :fields="fields"
  formLayout="vertical"
  :formData="formData"
  :defaultSpan="8"
>
          <template #sex="{ field, formData }">
              <div>
                  <a-input v-model:value="formData.sex" placeholder="你好"></a-input>
              </div>
          </template>
</CustomForm>

看示例,作用域插槽绑定的插槽名,就是你定义的那条数据的name属性值,#sex, 同时你可以在你插入的内容中绑定数据,作用域插槽把数据都给你传递回来了,如何绑定?formData是用于回显的数据对象,给他绑定上对应,即:formData就是formData

formLayout

formLayout就是form表单如何布局,ant给了三种属性值 分别是

| horizontal | 默认值 | | ---------- | ------ | | vertical | | | inline | |

defaultSpan

defaultSpan就是你表单默认占多少位置,如果数据设置了span,则会被替换掉,默认值是24份

formData

formData是数据初始值,可以用于数据初始化及数据回显

ref

用于获取表单的实例对象,用于表单的提交,可以通过他拿到所填数据,以及数据校验

const customForm = ref();
const onSubmit = () => {
    customForm.value.handleSubmit((formData: Record<string, any>) => {
        console.log("Form Submitted:", formData);
    });
};

formData就是你提交表单所需数据

dependency

用于根据前面表单的数据动态展示后面的表单 dependsOn: 绑定哪个表单? 他的值写绑定表单的绑定值 value:绑定表单选中某个值显示

  dependency: {
            dependsOn: "radioValue",
            value: "female",
  }

// 选中radioValue值,当他的值为female,则显示

slotFlag

这个主要是作用域表单的隐藏与显示,可以作为动态表单,slot插槽隐藏时,会有一块占地区域,如果不想要,则使用slotFlag,且自己在外部套用一层a-form-item

// 使用slot的插槽 隐藏占用位置
<template #associationProjectCode="{ field, formData }">
  <a-select
    v-model:value="formData.associationProjectCode"
    optionLabelProp="label"
    show-search
    placeholder="请选择诊疗项目"
    :default-active-first-option="false"
    :show-arrow="false"
    :filter-option="false"
    :not-found-content="null"
    :options="option"
    @search="handleSearch"
    @change="handleChange"
  ></a-select>
</template>

// 使用slotFlag的插槽 隐藏不占位置 建议在使用表单的事件时使用
<template v-if="treeId == 0" #memberProjectCategoryId="{ field, formData }">
  <a-form-item :label="field.label" :required="field.required" :name="field.formName">
    <a-select
      v-model:value="formData.memberProjectCategoryId"
      optionLabelProp="label"
      show-search
      placeholder="请选择诊疗项目"
      :default-active-first-option="false"
      :show-arrow="false"
      :filter-option="false"
      :not-found-content="null"
      :options="options"
      @search="handleSearch"
      @change="handleChange"
    ></a-select>
  </a-form-item>
</template>

动态表单建议使用dependency,而不是使用slotFlag,如果需要触发表单的某个事件时,使用slotFlag.

formRules

用于自定义表单,需要配合formName使用

    {
        name: "username",
        label: "姓名",
        type: "input",
        span: 12,
        formName: "username",
    },
const formRules = {
  username: [
    { required: true, message: 'Please input Activity name', trigger: 'change' },
    { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' }
  ]
}

5.下载使用

1.下载

npm i ant-base-form   //下载

2.在main.ts引入

import BaseForm from 'ant-base-form'
import 'ant-base-form/dist/style.css'

const app = createApp(App)
app.use(BaseForm)

注意,如若样式结构出现问题,则需要将ant组件库及样式先引入,再引入这个,同时使用是也放在ant后,如若未出现,则正常使用

3.在需要使用的组件中使用

<template>
  <BaseForm
    ref="baseForm"
    :fields="fields"
    formLayout="vertical"
    :formData="formData"
    :defaultSpan="8"
  >
    // 插槽
    <template #sex="{ field, formData }">
      <div>
        <a-input v-model:value="formData.sex" placeholder="你好"></a-input>
      </div>
    </template>
  </BaseForm>
</template>

<script lang="ts" setup>
// 初始值
const formData = {
  username: '',
  sex: '',
  aaaa: ''
}

// 生成表单类型
const fields = [
  {
    name: 'username',
    label: 'Username',
    type: 'input',
    errorMessage: '请输入姓名',
    required: true,
    span: 12
  },
  {
    name: 'sex',
    label: '性别',
    type: 'input',
    errorMessage: '请输入性别',
    required: true,
    slot: true,
    span: '24'
  },
  {
    name: 'aaaa',
    label: 'aaaaa',
    type: 'textarea',
    componentProps: {
      'auto-size': { minRows: 5, maxRows: 5 },
      maxlength: 10,
      'show-count': true
    },
    placeholder: '文本'
  }
]

// 点击提交  拿到表单数据
const baseForm = ref()

// 绑定表单的按钮,用于数据校验以及拿到数据
const onSubmit = () => {
  baseForm.value.handleSubmit((formData: Record<string, any>) => {
    console.log('Form Submitted:', formData)
  })
}
</script>

6.示例

// 初始值
const formData = {
    username: "",
    area: "",
    date: undefined,
    flag: true,
    checkbox: [],
    radio:"",
    remark:""
};

// 生成表单类型
const fields: any = [
    {
        name: "username",
        label: "姓名",
        type: "input",
        span: 12,
        formName: "username",
    },
    {
        name: "area",
        label: "地区",
        type: "select",
        span: "12",
        formName: "area",
        componentProps: {
            options: [
                { label: "苹果", value: "Apple" },
                { label: "梨", value: "Pear" },
                { label: "橘子", value: "Orange" },
            ],
        },
    },
    {
        name: "date",
        label: "时间",
        type: "date",
        span: "12",
        formName: "date",
        componentProps: {
            format: "YYYY/MM/DD",
        },
        forName: "date",
    },
    {
        name: "flag",
        label: "开关",
        type: "switch",
        span: "12",
    },
    {
        name: "checkbox",
        label: "多选",
        type: "checkbox",
        span: "12",
        componentProps: {
            options: [
                { label: "苹果", value: "Apple" },
                { label: "梨", value: "Pear" },
                { label: "橘子", value: "Orange" },
            ],
        },
    },
    {
        name: "radio",
        label: "单选",
        type: "radio",
        span: "12",
        componentProps: {
            options: [
                { label: "苹果", value: "Apple" },
                { label: "梨", value: "Pear" },
                { label: "橘子", value: "Orange" },
            ],
        },
    },
    {
        name: "remark",
        label: "备注",
        type: "textarea",
        span: "12",
    },
];

const formRules = {
    username: [
        { required: true, message: "Please input Activity name", trigger: "change" },
        { min: 3, max: 5, message: "Length should be 3 to 5", trigger: "blur" },
    ],
    area: [{ required: true, message: "Please select Activity zone", trigger: "change" }],
    date: [{ required: true, message: "Please pick a date", trigger: "change", type: "object" }],
};

// 点击提交  拿到表单数据
const baseForm = ref();

// 表单自定义校验
const onSubmit1 = () => {
    baseForm.value.customRuleSubmit((formData: Record<string, any>) => {
        console.log("Form Submitted:", formData);
    });
};

7.数据重置

baseForm.value.resetForm()

8.数据回显

baseForm.value.dataPlayBack(回显数据对象)

9.数据回显定义某一个数据或更改某一个数据

baseForm.value.formData.属性值 = 数据

10.监听数据,刷新列表

<BaseForm ref="baseForm" :fields="fields1" formLayout="inline" :defaultSpan="8"> </BaseForm>
// 1.定义数据类型
const fields = [
  {
    name: 'userName',
    label: '姓名',
    type: 'input'
  },
  {
    name: 'credentialsNumber',
    label: '身份证',
    type: 'input'
  }
]
// 2.传入后端参数
const obj = ref({
  userName: '',
  credentialsNumber: ''
})

// 方法1   3.监听参数
    watch(
        () => baseForm.value?.formData,
        () => {
          // 一定要给防抖,不然接口调用太快了
            throttle(() => {
                baseForm.value?.watchData((formData: Record<string, any>) => {
                    data.value = formData;
                    getList();
                });
            }, 500);
        },
        {
            deep: true,
        }
    );
// 3.方法2  监听参数
    watch(
        () => baseForm.value?.formData,
        () => {
          // 一定要给防抖,不然接口调用太快了
            throttle(() => {
                  data.value =  baseForm.value?.formData;
                  getList();
            }, 500);
        },
        {
            deep: true,
        }
    );

11.formData

这是最新的一个属性,目的是不再操作dom去调用数据 如何使用? 将他作为一个值传递给组件,包括所有表单的值,提交,数据回显,只要对其进行赋值即可,不再像以前调用ref组件中的方法才能获取到值,此组件仍然可以使用以前的ref方法

v-model:formData="formData"

12. commonRules,customRules

第一个是通用的校验函数,第二个是自定义的校验函数,不再只是是点击按钮再去校验,true为通过,反之则不通过 baseForm.value.commonRules()
baseForm.value.customRules()