antd表单文本域(扩展带输入字符数量)二次封装

背景

项目是基于antd,需求表单中文本域要求显示当前输入文案字数以及最大限制字数。

实现难点

  1. 表单校验总是不触发
    antd中form-model的校验规则很奇怪,form-item标签下面添加一层标签,校验规则就不触发了,如下多加一层div:
 <a-form-model ref="basicInfo" class="basic-info" :model="prodBasicInfo" :rules="rules" layout="inline">
    <a-form-model-item label="商品副标题" prop="slogan">
      <div>
    	 <a-input v-model="prodBasicInfo.slogan" style="width: 700px" placeholder="最多50个字" :maxLength="50" />
      </div>
    </a-form-model-item>
    ...
<a-form-model>

	rules: {
        slogan: [
          { required: true, message: "商品副标题不能为空", trigger: "blur" },
          { max: 20, message: "名称最多20个字", trigger: "blur" },
        ],
    }

上续情况表单失去焦点事件就校验不触发,那封装组件自然会外套一个标签,本文需要封装的组件dom结构会如下:

 <div class="textarea">
    <a-input
      v-model="textValue"
      type="textarea"
      class="text-area"
      :maxLength="maxLength"
      :autoSize="autoSize"
      :placeholder="placeholder"
      @input="onInput"
      @blur="handleBlur"
    />
    <span class="fontNum-prompt">{{ value.length }}/{{ maxLength }}</span>
  </div>

自然也是校验规则 不触发

解决办法

绑定a-input的失焦事件,将当前表单中的值 抛出去;就可以校验 ----不懂为什么,但确实可以做到;

总体实现代码如下:

<!-- 二次封装 ant 文本框,添加【已输长度/最多长度】显示 -->
<template>
  <div class="textarea-plus">
    <a-input
      v-model="textValue"
      type="textarea"
      class="text-area"
      :maxLength="maxLength"
      :autoSize="autoSize"
      :placeholder="placeholder"
      @input="onInput"
      @blur="handleBlur"
    />
    <span class="fontNum-prompt">{{ value.length }}/{{ maxLength }}</span>
  </div>
</template>

<script>
export default {
  name: "AntTextarea",
  props: {
    value: {
      type: [String, Number],
      default: null,
    },
    placeholder: {
      type: String,
      default: "",
    },
    maxLength: {
      type: Number,
      default: null,
    },
    autoSize: {
      type: Object,
      default() {
        return {
          minRows: 2,
        };
      },
    },
  },
  data() {
    return {
      textValue: this.value,
    };
  },
  methods: {
    handleBlur(e) {
      // this.$emit("update:value", e.target.value);
      this.$emit("blur", e.target.value);
    },
    onInput(e) {
      this.$emit("update:value", e.target.value);
      // this.$emit("input", e.target.value);
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
.textarea-plus {
  position: relative;
  .text-area {
    padding-bottom: 30px;
  }
  .fontNum-prompt {
    position: absolute;
    bottom: 10px;
    right: 20px;
    line-height: 20px;
    color: rgba(0, 0, 0, 0.3);
  }
}
</style>


版权声明:本文为keruisiya原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。