表单 form 待优化 待新增

用于收集整合表单组件,统一验证、提交表单数据

使用说明

提示

所有表单组件均可使用form组件组功能

简单引入

通过from组件定义表单区域,你可以从默认插槽中获取一个方法submit,为任意一个表单区域内元素绑定该方法,调用该方法后,会触发组件submit事件,获取到表单数据集与规则匹配结果

需要与form-item组件配合使用,你可以通过为该组件绑定rules数组进行规则匹配,匹配传入方式请参考下方代码

你需要为每一个表单组件都绑定name属性,否则submit事件无法传回正确的数据集

昵称
性别
未知
爱好
吃饭睡觉打游戏
所在地
请选择
出生日期
请选择
选定时间
请选择
是否提醒
展开代码
<template>
  <vi-form style="--vi-form-label-gap: 1em; --vi-form-item-gap: .5em;" @submit="(res, valid) => console.log(res, valid)">
    <template v-slot="{ submit }">
      <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]">
        <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
      </vi-form-item>
      <vi-form-item label="性别" :rules="[{rule: '.', info: '请选择一个性别'}]">
        <vi-radio-group name="sex" v-model="sex">
          <vi-radio value="male"></vi-radio>
          <vi-radio value="female"></vi-radio>
          <vi-radio value="unknown">未知</vi-radio>
        </vi-radio-group>
      </vi-form-item>
      <vi-form-item label="爱好" :rules="[{rule: (val) => val.length !== 0, info: '至少选择一项'}]">
        <vi-checkbox-group name="like" v-model="like">
          <vi-checkbox value="eating">吃饭</vi-checkbox>
          <vi-checkbox value="sleep">睡觉</vi-checkbox>
          <vi-checkbox value="play game">打游戏</vi-checkbox>
        </vi-checkbox-group>
      </vi-form-item>
      <vi-form-item label="所在地" :rules="[{rule: /./, info: '请选择一个城市'}]">
        <vi-select name="place" v-model="place" type="plain" choose-type="plain">
          <vi-option value="上海"></vi-option>
          <vi-option value="北京"></vi-option>
          <vi-option value="成都"></vi-option>
          <vi-option value="深圳"></vi-option>
        </vi-select>
      </vi-form-item>
      <vi-form-item label="出生日期" :rules="[
        {
          rule: (d) => d.year !== undefined,
          info: '请选择您的出生日期'
        },
        {
          rule: (d) => {
            return new Date(d.year, d.month - 1, d.date).valueOf() <= Date.now()
          }, 
          info: '出生日期应早于今日'
        }]">
        <vi-date-select name="birthday" v-model="birthday" type="plain" format="YYYY年MM月DD日"></vi-date-select>
      </vi-form-item>
      <vi-form-item label="选定时间">
        <vi-time-select name="time" v-model="time" type="plain"></vi-time-select>
      </vi-form-item>
      <vi-form-item label="是否提醒" :rules="[{ rule: 'true', info: '必须开启提醒'}]">
        <vi-switch name="vd" v-model="mention"></vi-switch>
      </vi-form-item>
      <vi-button @click="submit">提交数据</vi-button>
    </template>
  </vi-form>
</template>

<script setup>
  import { ref, reactive } from 'vue'
  const nickname = ref()
  const sex = ref()
  const like = reactive([])
  const place = ref()
  const birthday = reactive({})
  const time = reactive({})
  const mention = ref(false)
</script>

WARNING

你可以为规则传入正则表达式(字符串形式与对象形式)和函数(函数的第一个参数会返回表单绑定的值,你需要返回一个boolean值)

规则匹配数组按下标顺序依次执行,当出现匹配失败情况后会停止后续匹配,并显示第一个出现错误的匹配信息

匹配结果自反馈 新功能

通过函数getSubmitFeedback(infoMap: Map<string, string>),可以向表单提供动态的匹配结果集,若调用该函数,attention将重置并展示feedBackMap中提供的提示信息

如果你需要使用该功能,你需要调用函数传入一个结果反馈集,键为表单name,值为反馈内容

该函数可从默认插槽中获取,或者从submit事件中第三个option参数中解构获得

昵称
爱好
吃饭睡觉打游戏
展开代码
<template>
  <vi-form style="--vi-form-label-width: 2em;" @submit="handleSubmit">
    <template v-slot="{ submit, getSubmitFeedback }">
      <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]">
        <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
      </vi-form-item>
      <vi-form-item label="爱好" :rules="[{rule: (val) => val.length !== 0, info: '至少选择一项'}]">
        <vi-checkbox-group name="like" v-model="like">
          <vi-checkbox value="eating">吃饭</vi-checkbox>
          <vi-checkbox value="sleep">睡觉</vi-checkbox>
          <vi-checkbox value="play game">打游戏</vi-checkbox>
        </vi-checkbox-group>
      </vi-form-item>
      <vi-button @click="submit">提交</vi-button>
    </template>
  </vi-form>
</template>
<script setup>
  function handleSubmit (formMap, r, { resMap, getSubmitFeedback}) {
    const feedBackMap = new Map()
    console.log('ok')
    feedBackMap.set('nickname', '这是自反馈内容')
    getSubmitFeedback(feedBackMap)
  }
</script>

立即规则匹配

为对应form-item组件绑定auto属性,当表单内容改变时,立刻进行规则匹配

昵称
展开代码
<template>
  <vi-form style="--vi-form-label-width: 2em;">
    <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" auto>
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
  </vi-form>
</template>

首次立即规则匹配 新功能

为对应form-item组件绑定immediate属性,立刻进行首次规则匹配

昵称
昵称
您还没有输入昵称
展开代码
<template>
  <vi-form style="--vi-form-label-width: 2em;">
    <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" auto>
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
        <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" immediate>
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
  </vi-form>
</template>

规则匹配截断 新功能

为对应form-item组件绑定trunc属性,当表单数据匹配失败后,停止后续匹配

性别
未知
爱好
吃饭睡觉打游戏
展开代码
<template>
  <vi-form style="--vi-form-label-width: 2em;">
    <template v-slot="{ submit }">
      <vi-form-item label="性别" :rules="[{rule: '.', info: '请选择一个性别'}]" trunc>
        <vi-radio-group name="sex" v-model="sex">
          <vi-radio value="male"></vi-radio>
          <vi-radio value="female"></vi-radio>
          <vi-radio value="unknown">未知</vi-radio>
        </vi-radio-group>
      </vi-form-item>
      <vi-form-item label="爱好" :rules="[{rule: (val) => val.length !== 0, info: '至少选择一项'}]">
        <vi-checkbox-group name="like" v-model="like">
          <vi-checkbox value="eating">吃饭</vi-checkbox>
          <vi-checkbox value="sleep">睡觉</vi-checkbox>
          <vi-checkbox value="play game">打游戏</vi-checkbox>
        </vi-checkbox-group>
      </vi-form-item>
      <vi-button @click="submit">提交</vi-button>
    </template>
  </vi-form>
</template>

行内块显示

通过为对应form-item绑定不同type属性,控制其元素块类型

昵称
性别
未知
爱好
吃饭睡觉打游戏
所在地
请选择
展开代码
<template>
  <vi-form>
      <vi-form-item label="昵称">
        <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
      </vi-form-item>
      <vi-form-item label="性别" type="inline" style="--vi-form-item-width: 200px;">
        <vi-radio-group name="sex" v-model="sex">
          <vi-radio value="male"></vi-radio>
          <vi-radio value="female"></vi-radio>
          <vi-radio value="unknown">未知</vi-radio>
        </vi-radio-group>
      </vi-form-item>
      <vi-form-item label="爱好" type="inline">
        <vi-checkbox-group name="like" v-model="like">
          <vi-checkbox value="eating">吃饭</vi-checkbox>
          <vi-checkbox value="sleep">睡觉</vi-checkbox>
          <vi-checkbox value="play game">打游戏</vi-checkbox>
        </vi-checkbox-group>
      </vi-form-item>
      <vi-form-item label="所在地">
        <vi-select name="place" v-model="place" type="plain" choose-type="plain">
          <vi-option value="上海"></vi-option>
          <vi-option value="北京"></vi-option>
          <vi-option value="成都"></vi-option>
          <vi-option value="深圳"></vi-option>
        </vi-select>
      </vi-form-item>
  </vi-form>
</template>

不绑定表单名

通过label你可以为表单绑定展示名,你也可以不传入label

需要注意的是,如果所有表单都没有label,你需要通过css变量--vi-form-label-width将label宽度调整为0

展开代码
<template>
  <vi-form style="--vi-form-label-width: 0;">
    <vi-form-item >
      <vi-input name="username" placeholder="请输入账号"></vi-input>
    </vi-form-item>
    <vi-form-item>
      <vi-input name="password" placeholder="请输入密码" password show-password></vi-input>
    </vi-form-item>
  </vi-form>
</template>

label布局

form-item组件通过align属性控制label对齐方式

账号
账号密码
rightleftupdown
展开代码
<template>
  <vi-form>
    <vi-form-item label="账号" :align="choose">
      <vi-input name="username"></vi-input>
    </vi-form-item>
    <vi-form-item label="账号密码" :align="choose">
      <vi-input name="password" password show-password></vi-input>
    </vi-form-item>
  </vi-form>
  <vi-divider/>
  <vi-radio-group name="align-choose" v-model="choose">
    <vi-radio value="right"/> 
    <vi-radio value="left"/>
    <vi-radio value="updown"/>
  </vi-radio-group>
</template>

尺寸

通过size属性修改form-item大小

昵称
昵称
昵称
展开代码
<template>
  <vi-form style="--vi-form-label-width: 2em; --vi-form-item-gap: 2em;">
    <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" auto size="big">
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
    <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" auto>
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
    <vi-form-item label="昵称" :rules="[{rule: /./, info: '您还没有输入昵称'}]" auto size="small">
      <vi-input name="nickname" placeholder="输入昵称" v-model="nickname" type="plain"></vi-input>
    </vi-form-item>
  </vi-form>
</template>

Props

form

属性名描述类型默认值

form-item

属性名描述类型默认值

插槽

from

插槽名描述有无默认内容

from-item

插槽名描述有无默认内容

事件

from-item

事件名描述参数列表

css变量

变量名描述默认值