拿来即用的小程序vue表单提交封装通用组件

组件页面代码 

<template>
  <div class="form-block">
    <div class="w-form">
      <div class="w-field" v-for="(f,f_index) in fields" :key="f_index">
        <div class="w-row">
          <div class="w-title" :class="f.required?'w-start':''">{{ f.name }}</div>
          <div class="w-val">
            <input type="text" v-if="f.type==='text'" v-model="formData[f.field]" :placeholder="f.placeholder" :maxlength="f.maxlength">
            <input type="digit" v-else-if="f.type==='digit'" v-model="formData[f.field]" :placeholder="f.placeholder" :maxlength="f.maxlength">
            <input type="number" v-else-if="f.type==='number'" v-model="formData[f.field]" :placeholder="f.placeholder" :maxlength="f.maxlength">
            <radio-group class="w-radio" @change="radioChange($event,f)" v-else-if="f.type==='radio'">
              <div class="radio-item" v-for="(r,r_index) in f.radioData" :key="r_index">
                <div class="r-val">
                  <radio :value="r.value" :data-model="f.field"/>
                </div>
                <div class="r-name">{{ r.name }}</div>
              </div>
            </radio-group>
          </div>
        </div>
        <div class="f-errors" v-if="errors[f.field]">{{ errors[f.field] }}</div>
      </div>
      <div class="w-but">
        <button @click="handleSubmit">提交</button>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "FormPage",
  props: {
    fields: {
      type: Array,
      required: true
    },
    initialData: {
      type: Object,
      required: false,
      default: () => ({})
    }
  },
  data() {
    return {
      formData: this.initialData,
      errors: {}
    }
  },
  methods: {
    radioChange(e, f) {
      f.radioData.forEach(r => {
        if (r.value == e.target.value) {
          this.formData[f.field] = r.value
        }
      })
    },
    validate() {
      this.errors = {}; // 清空上一次的错误信息
      let isValid = true;
      this.fields.forEach(f => {
        if (f.required && !this.formData[f.field]) {
          this.errors[f.field] = '必填项不可以为空'
          isValid = false;
        }
        if (['digit', 'number'].includes(f.type) && this.formData[f.field]) {
          if (!this.checkNumber(this.formData[f.field], f.checkType)) {
            this.errors[f.field] = '请输入正确的数字'
            isValid = false;
          }
        }
      });
      return isValid;
    },
    checkNumber: function (number, type) {
      switch (type) {
        case 1: //手机号
          return /^1([3456789])\d{9}$/.test(number);
        case 2: //可以有两位小数的数字 金额使用
          return /^([0-9])+(\.[0-9]{1,2})?$/.test(number);
        case 0:
        default:  //非零正整数
          return /^[1-9]\d*$/.test(number);
      }
    },
    handleSubmit() {
      if (this.validate()) {
        this.$emit('formSubmit', this.formData);
      }
    }
  },
  watch: {
    initialData: {
      handler(newData) {
        this.formData = newData;
        this.errors = {}
      },
      deep: true
    }
  }
}
</script>
<style scoped lang="scss">
.form-block {
  background-color: #EFF2F5;
  width: calc(100vw - 40rpx);
  height: 100vh;
  padding: 20rpx;
  position: fixed;

  .w-form {
    font-size: 24rpx;
    padding: 20rpx;
    background-color: white;
    border-radius: 20rpx;

    .w-start::after {
      content: '*';
      color: red;
    }

    .w-field {
      border-bottom: 1rpx solid #eceeee;
      margin-bottom: 20rpx;
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      line-height: 60rpx;

      .w-row {
        display: inline-flex;
        width: 100%;
        gap: 20rpx;

        .w-title {
          width: 30%;
        }

        .w-val {
          width: 70%;

          input {
            padding: 0 15rpx;
            height: 100%;
            width: 100%;
          }

          .w-radio {
            display: flex;
            flex-wrap: wrap;
            gap: 20rpx;

            .radio-item {
              display: flex;

              radio {
                transform: scale(0.8);
              }
            }
          }
        }
      }

      .f-errors {
        color: red;
        font-size: 20rpx;
        width: 100%;
        text-align: right;
      }
    }

    .w-but {
      width: 100%;
      text-align: center;
      margin: 30rpx 0;

      button {
        background-color: #1989FA;
        color: white;
        border-radius: 20rpx;
        width: 95%;
        font-size: 26rpx;
      }
    }
  }
}
</style>

引入例子

<template>
  <div>
    <FormPage :fields="fields" :initial-data="initialFormData" @formSubmit="formSave"></FormPage>
  </div>
</template>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值