應用十二: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 {
      width: 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;
      width: calc(100% - 28px);
    }
    .el-button--small {
      width: auto;
    }
    .my-form .el-input__inner, .my-table .el-input__inner {
      width: 160px;
      height: 30px;
      line-height: 30px;
    }
    .detail-info .el-input__inner {
      width: 480px;
    }
    .el-textarea__inner {
      width: 625px;
    }
  }
</style>
View Code

 

以上就是關於動態表單實現及校驗的分享,有任何疑問和不足歡迎留言並指正!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM