# form

组件类型:UniFormElement

表单

# 兼容性

Web 微信小程序 Android iOS HarmonyOS
4.0 4.41 3.97 4.11 4.61

# 属性

名称 类型 默认值 兼容性 描述
disabled boolean -
是否禁用
report-submit boolean -
是否返回 formId 用于发送模板消息
@submit (event: UniFormSubmitEvent) => void -
携带 form 中的数据触发 submit 事件,event.detail = {value : {'name': 'value'}}
@reset (event: UniFormResetEvent) => void -
表单重置时会触发 reset 事件
report-submit-timeout number -
-

# 事件

# UniFormSubmitEvent

# UniFormSubmitEventDetail
# UniFormSubmitEventDetail 的属性值
名称 类型 必填 默认值 兼容性 描述
value UTSJSONObject - - -

# UniFormResetEvent

# form内容项控制逻辑

form组件的内容子组件包括:input、textarea、checkbox、radio、switch、slider,以及负责提交或重置的button组件。

button可以设置form-type属性为submit或reset,点击时会分别触发form的提交或重置。

在表单submit或reset时,这些表单内容子组件的值会被提交或重置。

注意:目前不支持上述组件之外自行添加表单内容子组件。如有自定义组件,则不能使用form组件提交,需自行通过绑定data的方式获取组件值并自行编码提交数据。

# submit策略差异

form 组件的表单提交,微信小程序的实现策略,与浏览器W3C的策略略有差异。目前uni-app(x)在submit时,app和web上的实现与微信小程序相同。具体是:

  • uni-app表单提交的数据是一个对象{"name": "value"}。而浏览器标准form是数组,每项为 pair,pair[0] 对应name,pair[1] 对应value 。
  • 多个表单子项如果 name 相同,仅保留最后一个表单子项。而浏览器标准form整体是数组,不存在覆盖的情况。
  • 设置 disabled 属性的表单子项,仍然会提交。而浏览器标准form提交时会忽略disabled的表单子项。

注意uni-app(x)编译到web平台,也是按uni-app(x)的策略,而不是浏览器的策略。uni-app(x) 的 web平台使用 uni-app 自己的 form 组件,而不是浏览器的 form 标签。

# reset策略差异

reset在浏览器W3C的策略是还原、重置。

在uni-app(x)中,不同平台的策略不同,有的是还原,有的是清空

各平台策略如下:

uni-app-x

App Web
还原(3.97+) 还原(4.0+)

uni-app

App Web 微信小程序 支付宝小程序 百度小程序 抖音小程序
清空 清空 清空 还原 清空 清空
  1. 还原初始值
<!-- reset 后为 name -->
<input name="input1" value="name" />

<!-- reset 后为 true -->
<switch name="switch1" :checked="true" />

<!-- reset 后为 50 -->
<slider name="slider1" :value="50" :min="10" :max="110" />

<!-- reset 后为 "写字" 被 checked -->
<checkbox-group name="loves">
  <view>
    <checkbox value="0" /><text>读书</text>
  </view>
  <view>
    <checkbox value="1" :checked="true" /><text>写字</text>
  </view>
</checkbox-group>
  1. 清空已有值(含初始值和改变后的值)
<!-- reset 后为 "" -->
<input name="input1" value="name" />

<!-- reset 后为 false -->
<switch name="switch1" :checked="true" />

<!-- reset 后为 最小值10 -->
<slider name="slider1" :value="50" :min="10" :max="110" />

<!-- reset 后为 无任何 checked -->
<checkbox-group name="loves">
  <view>
    <checkbox value="0" /><text>读书</text>
  </view>
  <view>
    <checkbox value="1" :checked="true" /><text>写字</text>
  </view>
</checkbox-group>

# 示例

hello uni-app x

扫码体验(手机浏览器跳转到App直达页)

Template

Script

<template>
  <!-- #ifdef APP -->
  <scroll-view class="scroll-view">
  <!-- #endif -->
    <view class="page">
      <form @submit="onFormSubmit" @reset="onFormReset">
        <view class="uni-form-item">
          <text class="title">姓名</text>
          <input class="uni-input" name="nickname" :value="nickname" placeholder="请输入姓名" maxlength="-1" />
        </view>
        <view class="uni-form-item">
          <text class="title">性别</text>
          <radio-group name="gender" class="flex-row">
            <view class="group-item">
              <radio value="0" :checked="gender=='0'" /><text></text>
            </view>
            <view class="group-item">
              <radio value="1" :checked="gender=='1'" /><text></text>
            </view>
          </radio-group>
        </view>
        <view class="uni-form-item">
          <text class="title">爱好</text>
          <checkbox-group name="loves" class="flex-row">
            <view class="group-item">
              <checkbox value="0" :checked="loves.indexOf('0')>-1" /><text>读书</text>
            </view>
            <view class="group-item">
              <checkbox value="1" :checked="loves.indexOf('1')>-1" /><text>写字</text>
            </view>
          </checkbox-group>
        </view>
        <view class="uni-form-item">
          <text class="title">年龄</text>
          <slider name="age" :value="age" :show-value="true"></slider>
        </view>
        <view class="uni-form-item">
          <text class="title">保留选项</text>
          <view>
            <switch name="switch" :checked="switch" />
          </view>
        </view>
        <view class="uni-form-item">
          <text class="title">备注</text>
          <textarea name="comment" :value="comment" placeholder="请输入备注" style="background: #FFF;" />
          <!-- <textarea class="uni-input" name="comment" :value="comment" placeholder="这个class的写法,导致iOS和Android产生了高度差异"/> -->
        </view>
        <!-- picker -->
        <!-- #ifdef APP-HARMONY -->
        <view class="uni-form-item flex-row">
          <text class="title">时区</text>
          <picker class="picker" name="timeZone" @change="onTimeZoneChange" :value="timeZoneIndex" :range="timeZoneList">
            <view class="uni-input pickerValue">{{timeZoneList[timeZoneIndex]}}</view>
          </picker>
        </view>
        <view class="uni-form-item flex-row">
          <text class="title">多列选择器</text>
          <picker class="picker pickerMulti" mode="multiSelector" @columnchange="onMultiPickerColumnChange"
            :value="multiIndex" :range="multiArray">
            <view class="uni-input pickerMultiValue">
              {{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}
            </view>
          </picker>
        </view>
        <view class="uni-form-item flex-row">
          <text class="title">时间选择器</text>
          <picker class="picker pickerTime" mode="time" :value="timePickerValue" start="09:01" end="21:01" @change="onTimeChange">
            <view class="uni-input">{{timePickerValue}}</view>
          </picker>
        </view>
        <view class="uni-form-item flex-row">
          <text class="title">日期选择器</text>
          <picker class="picker pickerDate" mode="date" :value="datePickerValue" :start="startDate" :end="endDate"
            @change="onDateChange">
            <view class="uni-input">{{datePickerValue}}</view>
          </picker>
        </view>
        <!-- #endif -->
        <view class="uni-form-item">
          <text class="title">时间</text>
          <picker-view class="picker-view" name="time" :value="time">
            <picker-view-column>
              <view class="picker-view-item" v-for="(item,index) in hours" :key="index">
                <text class="picker-view-text">{{item}}时</text>
              </view>
            </picker-view-column>
            <picker-view-column>
              <view class="picker-view-item" v-for="(item,index) in minutes" :key="index">
                <text class="picker-view-text">{{item}}分</text>
              </view>
            </picker-view-column>
          </picker-view>
        </view>
        <view class="flex-row">
          <button class="btn btn-submit" form-type="submit" type="primary">Submit</button>
          <button class="btn btn-reset" type="default" form-type="reset">Reset</button>
        </view>
      </form>
      <view class="result">提交的表单数据</view>
      <textarea class="textarea" :value="formDataText" :maxlength="-1" :auto-height="true"></textarea>
    </view>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>



<style>
  .scroll-view {
    flex: 1;
  }

  .page {
    padding: 15px;
  }

  .flex-row {
    flex-direction: row;
    align-items: center;
  }

  .uni-form-item {
    padding: 15px 0;
  }

  .title {
    margin-bottom: 10px;
    opacity: 0.8;
  }

  .picker {
    margin-left: 15px;
  }

  .group-item {
    flex-direction: row;
    margin-right: 20px;
  }

  .picker-view {
    width: 200px;
    height: 320px;
    margin-top: 10px;
  }

  .picker-view-item {
    height: 50px;
  }

  .picker-view-text {
    line-height: 50px;
    text-align: center;
  }

  .btn {
    flex: 1;
  }

  .btn-submit {
    margin-right: 5px;
  }

  .btn-reset {
    margin-left: 5px;
  }

  .result {
    margin-top: 30px;
  }

  .textarea {
    margin-top: 5px;
    padding: 5px;
    background-color: #fff;
  }
</style>

# 参见