zoukankan      html  css  js  c++  java
  • 应用十二:Vue之动态表单的实现及校验

    该篇仍然使用Vue + TypeScript的语法,以近期项目中的实例来做分享~

    动态表单实现

    首先给出页面展示效果:

    该页面分为上下两部分,上面是静态表单部分,下面是动态的实现。简单来说就是每点击一次批量添加按钮就会新增一行设备信息表单,点击后面的移除就会删掉当前表单行。

    静态表单就不多说了,动态表单的具体实现逻辑是:

    1、将每一行的表单作为一个单独的组件进行封装。

    2、使用一个数组来存储多个表单(也就是上一步封装的组件)并循环展示。

    代码实现如下:

    其中device-info就是封装好的组件,组件的完整实现如下:

    <template>
      <div class="deviceInfo">
          <el-row>
            <el-col :span="6">
              <el-form-item label="设备编号" :prop="'list.'+index+'.deviceCode'" :rules="{
                  required: true, message: '设备编号不能为空', trigger: 'blur'
                }">
                <el-input v-model="deviceInfo.deviceCode" clearable placeholder="" maxlength="20"
                @keyup.native="deviceInfo.deviceCode=deviceInfo.deviceCode.replace(/[^w./]/ig,'').toUpperCase()"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="设备品牌" :prop="'list.'+index+'.brandCode'" :rules="{
                  required: true, message: '设备品牌不能为空', trigger: 'change'
                }">
                <el-select v-model="deviceInfo.brandCode" placeholder="" @change="handleChangeBrand">
                  <el-option v-for="item in DEVICE_BRAND" :key="item.modelCode" :label="item.modelName" :value="item.modelCode"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="设备型号" :prop="'list.'+index+'.modelCode'" :rules="{
                  required: true, message: '设备型号不能为空', trigger: 'change'
                }">
                <el-select v-model="deviceInfo.modelCode" placeholder="">
                  <el-option v-for="item in DEVICE_MODEL" :key="item.modelCode" :label="item.modelName" :value="item.modelCode"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label=" " v-if="list.length > 1">
                <el-button class="remove" type="primary" @click="removeComponent">移除</el-button>
              </el-form-item>
            </el-col>
          </el-row>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Prop, Emit } from 'vue-property-decorator'
    import ReportVO from '@/entity/MaintainManage/Report.ts'
    
    @Component
    export default class DeviceInfo extends Vue {
      @Prop({ default: 0 }) private index!: number  // 当前组件索引
      @Prop() private deviceInfo!: ReportVO  // 当前组件数据对象
      @Prop() private list!: Array<any>  // 存储组件的集合
    
      private DEVICE_BRAND: Array<Object> = []
      private DEVICE_MODEL: Array<Object> = []
    
      private mounted(): void {
        // 后台获取设备品牌 TODO
      }
    
      public handleChangeBrand(item: string) {
        // 后台根据品牌获取设备型号 TODO
      }
      
      @Emit('removeComponent')
      public removeComponent() {
        return this.index
      }
    }
    </script>
    
    <style lang="scss">
      .deviceInfo {
        .el-textarea__inner {
           420px;
        }
        .remove {
          color: #FAFAFA;
          background: #F56C6C;
          border-color: #F56C6C;
        }
      }
    </style>
    View Code

    动态表单的批量添加和移除功能的实现如下:

    动态表单校验

    同样先给出页面表单校验的展示效果:

    虽然整个页面分为上下静态表单和动态表单两部分,但用的是一个按钮一次提交的,为了实现统一校验,所以整个页面最好使用一个el-form标签包裹起来,静态表单的校验请参考《应用二:Vue之ElementUI Form表单校验》,而动态表单的校验有两个地方需要注意,一个是el-form-item标签上prop属性的写法,另一个就是校验规则的写法(只能写在标签上),具体写法如下:

    prop的属性值中,listform对象中存储组件的数组,index是当前组件在数组中的索引,deviceCode就是当前表单绑定的字段,可以参考前面组件的完整实现代码。

    下面给出整个页面的完整代码:

    <template>
      <div class="maintainReport">
        <el-form ref="form" :model="form" :inline="true" label-width="120px" :rules="rules">
          <div class="my-form">
            <div class="my-title">添加寄件信息</div>
            <el-row>
              <el-col :span="6">
                <el-form-item label="寄件人" prop="loginWorkName">
                  <el-input v-model="form.loginWorkName" clearable placeholder=""></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="寄件人电话" prop="linkTel">
                  <el-input v-model="form.linkTel" clearable placeholder=""></el-input>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="寄送单号" prop="sendCode">
                  <el-input v-model="form.sendCode" clearable placeholder="" maxlength="18" @keyup.native="form.sendCode=form.sendCode.replace(/[^w./]/ig,'').toUpperCase()"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
          <div class="my-table">
            <div class="my-title fl">添加设备信息</div>
            <div class="btn-table">
              <div class="btn-l">
                <el-button type="primary" icon="el-icon-circle-plus-outline" @click="addComponent">批量添加</el-button>
              </div>
            </div>
            <div class="clear" v-for="(item, $index) in form.list" :key="$index">
              <device-info :index="$index" :deviceInfo="item" :list="form.list" @removeComponent="removeComponent"></device-info>
              <hr style="border: 1px dashed #f3edf5;" v-if="$index!=form.list.length-1">
            </div>
          </div>
        </el-form>
        <div style="text-align: center;margin-top: 20px;">
          <el-button type="primary" plain @click="submitReport">维修上报提交</el-button>
        </div>
      </div>
    </template>
    
    <script lang="ts">
    import { Component, Vue, Ref } from 'vue-property-decorator'
    import MyVue from '@/utils/myVue.ts'
    import DeviceInfo from '@/views/MaintainManage/components/DeviceInfo.vue'
    
    @Component({
      components: {
        'device-info': DeviceInfo
      }
    })
    export default class MaintainReport extends MyVue {
      // data
      private form: any = {
        loginWorkName: '',
        linkTel: '',
        list: [{
          deviceCode: '',
          brandCode: '',
          modelCode: ''
        }]
      }
    
      private rules: any = {
        loginWorkName: [{required: true, message: '寄件人不能为空', trigger: 'blur'}],
        linkTel: [{required: true, message: '寄件人电话不能为空', trigger: 'blur'},
          {pattern: "^(1[3-9]{1}\d{9})$", message: '电话格式不正确', trigger: 'blur'}]
      }
    
      public addComponent() {
        this.form.list.push({
          deviceCode: '',
          brandCode: '',
          modelCode: ''
        })
      }
      public removeComponent(index: number) {
        this.form.list.splice(index, 1);
      }
    
      @Ref('form') readonly submitForm!: any
      // 维修上报提交
      public submitReport() {
        this.submitForm.validate((valid: boolean) => {
          if (valid) {
            // TODO
          }
        })
      }
    }
    </script>
    
    <style lang="scss">
      .maintainReport {
        .my-table .btn-table {
          left: 28px;
           calc(100% - 28px);
        }
        .el-button--small {
           auto;
        }
        .my-form .el-input__inner, .my-table .el-input__inner {
           160px;
          height: 30px;
          line-height: 30px;
        }
        .detail-info .el-input__inner {
           480px;
        }
        .el-textarea__inner {
           625px;
        }
      }
    </style>
    View Code

    以上就是关于动态表单实现及校验的分享,有任何疑问和不足欢迎留言并指正!!!

  • 相关阅读:
    经典之计算机内存管理
    Git 远程仓库
    【玩转微信公众平台之十】 图文消息回复解说
    C++11中的继承构造函数
    树莓派使用无线网卡上网相关命令
    swift的UITableView的使用
    相似微信的ChattingUi
    HDOJ 5289 Assignment 单调队列
    poj1936
    samba 文件和目录权限控制
  • 原文地址:https://www.cnblogs.com/fengyuexuan/p/12204971.html
Copyright © 2011-2022 走看看