表单校验,中文算两个字符,两种交互

812 阅读1分钟

最近再在做项目的过程中,产品在设计的输入的时候两种不同的交互。且中文算两个字符,input在输入的时候中文是一个字符,故maxlength属性不起作用,请看下面代码

效果图

屏幕快照 2021-03-13 下午6.44.02.png

vue+elementUI+ @keyup.native="limitStrLength"

场景一

<!--  -->
<template>
  <div class="form-page">
    <div class="form-box">
      <el-form
        :model="ruleForm"
        :rules="rules"
        ref="ruleForm"
        label-width="100px"
        class="demo-ruleForm"
      >
        <div class="tips">
          两种交互方式,1超出8个字符限制输入,2输入超出8个字符提示错误;注意中文算两个字符
        </div>
        <el-form-item label="活动名称一" prop="name1">
          <el-input
            v-model="ruleForm.name1"
            placeholder="最多输入4个中文"
          ></el-input>
        </el-form-item>
        <el-form-item label="活动名称二" prop="name2">
          <el-input
            v-model="ruleForm.name2"
            @keyup.native="(e) => limitStrLength(e, ruleForm.name2)"
            placeholder="最多输入4个中文"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('ruleForm')"
            >立即创建</el-button
          >
          <el-button @click="resetForm('ruleForm')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
   
      
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    var validateName1 = (rule, value, callback) => {
      if (value === "") {
        callback(new Error("请输入活动名称一"));
      } else {
        //获取输入的字符串长度
        let valLength = this.getStrLength(value);
        if (valLength > 8) {
          callback(new Error("活动名称一不能超出8个字符"));
        } else {
          callback();
        }
      }
    };
    return {
      ruleForm: {
        name1: "",
        name2: "wadwad",
      },
      rules: {
        name1: [{ required: true, validator: validateName1, trigger: "blur" }],
        name2: [
          { required: true, message: "请输入活动名称二", trigger: "blur" },
        ],
      },
      dynamicValidateForm: {
        domains: [
          {
            value: "",
          },
        ],
      },
    };
  },
  watch: {},
  mounted() {},
  methods: {
    //获取字符创长度
    getStrLength(str) {
      let length = str.length;
      let res = 0;
      for (var i = 0; i < length; i++) {
        if (str.charCodeAt(i) < 27 || str.charCodeAt(i) > 126) {
          // 全角
          res += 2;
        } else {
          res++;
        }
      }
      return res;
    },
    limitStrLength(e, data) {
      let input = e.target;
      let split = input.value.split("");
      // 计算已输入的长度
      let map = split.map((s, i) =>
        input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128
          ? 1
          : 2
      );
      //如果输入”我爱你520“  map = ['2','2','2','1','1','1']

      // 这里设置想要限制的长度
      let maxLength = 8;
      let n = 0;

      //获取输入的长度 charLength
      let charLength =
        map.length > 0 &&
        map.reduce((accumulator, currentValue, index) => {
          if (accumulator === maxLength || accumulator === maxLength - 1) {
            n = index;
          }
          return accumulator + currentValue;
        });

      if (charLength > maxLength) {
        input.value = split.slice(0, n).join("");
      }
      data = input.value; // data 传过来不是数据双向绑定
      this.$set(this.ruleForm, "name2", data); // this.ruleForm.name2 = data;
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          console.log("this.ruleForm.name2--------end", this.ruleForm.name2);
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
  },
};
</script>
<style lang="scss" scoped>
.form-page {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  .form-box {
    width: 800px;
    height: 600px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    .el-form {
      width: 100%;
      height: 100%;
    }
  }
  .tips {
    height: 60px;
    line-height: 60px;
  }
}
</style>

遇到的坑

在输入限制的时候,输出超出在输入框并没有显示,但是console.log(this.ruleForm.name2)你会发现字符超过了,eg:输入顺口溜123,在input框显示‘顺口溜12’,打印出来的数据‘顺口溜123’ 解决办法---重新赋值 this.ruleForm.name2 = input.value;

limitStrLength(e) {
      let input = e.target;
      let split = input.value.split("");
      // 计算已输入的长度
      let map = split.map((s, i) =>
        input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128 ? 1 : 2
      );
      //如果输入”我爱你520“  map = ['2','2','2','1','1','1']

      // 这里设置想要限制的长度
      let maxLength = 8;
      let n = 0;

      //获取输入的长度 charLength
      let charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
          if (accumulator === maxLength || accumulator === maxLength - 1) {
            n = index;
          }
          return accumulator + currentValue;
        });
       
      if (charLength > maxLength) {
        input.value = split.slice(0, n).join("");
      }
      this.ruleForm.name2 = input.value;
    },

场景二,循坏

<!--  -->
<template>
  <div class="form-page">
    <div class="form-box">
      <!-- 表单2 -->
      <el-form
        :model="dynamicValidateForm"
        ref="dynamicValidateForm"
        label-width="100px"
        class="demo-dynamic"
      >
        <el-form-item
          v-for="(domain, index) in dynamicValidateForm.domains"
          :label="'名称' + index"
          :key="domain.key"
          :prop="'domains.' + index + '.value'"
          :rules="{
            required: true,
            message: '名称不能为空',
            trigger: 'blur',
          }"
        >
          <el-input v-model="domain.value" @keyup.native="(e)=>limitStrLength(e,index)"></el-input
          ><el-button style="margin-left:10px" @click.prevent="removeDomain(domain)">删除</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('dynamicValidateForm')"
            >提交</el-button
          >
          <el-button @click="addDomain">新增名称</el-button>
          <el-button @click="resetForm2('dynamicValidateForm')">重置</el-button>
        </el-form-item>
      </el-form>
      
    </div>
   
      
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      dynamicValidateForm: {
        domains: [
          {
            value: "",
          },
        ],
      },
    };
  },
  watch: {},
  mounted() {},
  methods: {
    //获取字符创长度
    getStrLength(str) {
      let length = str.length;
      let res = 0;
      for (var i = 0; i < length; i++) {
        if (str.charCodeAt(i) < 27 || str.charCodeAt(i) > 126) {
          // 全角
          res += 2;
        } else {
          res++;
        }
      }
      return res;
    },
    limitStrLength(e, index) {
      let input = e.target;
      let split = input.value.split("");
      // 计算已输入的长度
      let map = split.map((s, i) =>
        input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128
          ? 1
          : 2
      );
      //如果输入”我爱你520“  map = ['2','2','2','1','1','1']

      // 这里设置想要限制的长度
      let maxLength = 8;
      let n = 0;

      //获取输入的长度 charLength
      let charLength =
        map.length > 0 &&
        map.reduce((accumulator, currentValue, index) => {
          if (accumulator === maxLength || accumulator === maxLength - 1) {
            n = index;
          }
          return accumulator + currentValue;
        });

      if (charLength > maxLength) {
        input.value = split.slice(0, n).join("");
      }
      // let obj = this.dynamicValidateForm.domains.find((item,index1) => index1 == index );
      // obj.value = input.value;
      this.$set(this.dynamicValidateForm.domains[index],'value',input.value)
      console.log("this.dynamicValidateForm.domains[index]--end",this.dynamicValidateForm.domains[index])

    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert("submit!");
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    resetForm2(formName) {
      this.$refs[formName].resetFields();
    },
    removeDomain(item) {
      var index = this.dynamicValidateForm.domains.indexOf(item);
      if (index !== -1) {
        this.dynamicValidateForm.domains.splice(index, 1);
      }
    },
    addDomain() {
      this.dynamicValidateForm.domains.push({
        value: "",
        key: Date.now(),
      });
    },
  },
};
</script>
<style lang="scss">
.el-form-item__content {
  display: flex !important;
}
</style>

数据双向未绑定

1623027956038.jpg

数据双向绑定

// let obj = this.dynamicValidateForm.domains.find((item,index1) => index1 == index );
// obj.value = input.value;
this.$set(this.dynamicValidateForm.domains[index],'value',input.value)
console.log("this.dynamicValidateForm.domains[index]--end",this.dynamicValidateForm.domains[index])

1623028069481.jpg