antdv Input组件maxLength属性设置默认值

在一个项目开发时,经常用到input组件或者textarea组件,当前项目使用的时[email protected]。提交测试时,测试人员反馈AInput和ATextarea组件没有限制字符长度导致保存时数据库插入报错,因此需要在前端需要限制字符长度。由于项目已经开发过半,因此想通过使用设置默认值方式设置maxLength属性。

确定方案

  1. 普通input最大长度默认设置为64
  2. textarea最大长度设置为200

最终实现

再main.js文件中增加代码

import Antd, { Input } from "ant-design-vue";
Input.props.maxLength.default = 64;

然后手动再将每个ATextarea单独增加:max-length="200"

踩坑过程

  1. 开始想通过修改默认值的方式分别修改AInput、ATextarea两类组件,代码如下:
    src\main.js
import Antd, { Input } from "ant-design-vue";
Input.props.maxLength.default = 64;
Input.TextArea.props.maxLength.default = 200;
  1. 运行结果
    结果发现AInput和ATextarea组件的maxlength都变成了200

  2. 原因查找
    \node_modules\ant-design-vue\es\input\TextArea.js使用函数式组件编写,核心代码如下

import inputProps from './inputProps';
var TextAreaProps = _extends({}, inputProps, {
  autosize: PropTypes.oneOfType([Object, Boolean]),
  autoSize: PropTypes.oneOfType([Object, Boolean])
});

export default {
  name: 'ATextarea',
  inheritAttrs: false,
  props: _extends({}, TextAreaProps),
  render: function render() {
     var props = {
       props: _extends({}, getOptionProps(this), {
         prefixCls: prefixCls,
         inputType: 'text',
         value: fixControlledValue(stateValue),
         element: this.renderTextArea(prefixCls),
         handleReset: this.handleReset
       }),
       on: getListeners(this)
     };
     return h(ClearableLabeledInput, props);
   }
}

ATextarea组件的props属性使用的_extends({}, TextAreaProps)进行浅拷贝


\node_modules\ant-design-vue\es\input\Input.js也使用函数式组件编写,代码如下:

import inputProps from './inputProps';
export default {
  name: 'AInput',
  inheritAttrs: false,
  props: _extends({}, inputProps),
  render: function render() {
    var props = {
      props: _extends({}, getOptionProps(this), {
      }),
      on: getListeners(this)
    };
    return h(ClearableLabeledInput, props);
  }
};

同样AInput组件的props属性也使用的_extends({}, inputProps)进行浅拷贝


node_modules\ant-design-vue\es\input\inputProps.js定义了props属性

import PropTypes from '../_util/vue-types';
export default {
  maxLength: PropTypes.number,
};

结论:PropTypes.number是引用类型,因此被浅拷贝后实际都是一个地址。无论给AInput还是ATextarea的maxlength赋默认值最终是相互影响的,所以导致上边的问题。


node_modules\ant-design-vue\es\_util\vue-types\index.js定义vue类型的公共代码

var VuePropTypes = {
  get number() {
    return toType('number', {
      type: Number
    }).def(currentDefaults.number);
  },
}

node_modules\ant-design-vue\es\_util\vue-types\utils.js定义vue类型的公共代码

/**
 * Adds `isRequired` and `def` modifiers to an object
 * @param {string} name - Type internal name
 * @param {object} obj - Object to enhance
 * @returns {object}
 */
export var toType = function toType(name, obj) {
  Object.defineProperty(obj, '_vueTypes_name', {
    enumerable: false,
    writable: false,
    value: name
  });
  withRequired(obj);
  withDefault(obj);//定义默认值,实际上为obj添加了一个def方法,通过该方法定义默认值
  if (isFunction(obj.validator)) {
    obj.validator = obj.validator.bind(obj);
  }
  return obj;
};

/**
 * Adds a `def` method to the object returning a new object with passed in argument as `default` property
 * @param {object} type - Object to enhance
 */
export var withDefault = function withDefault(type) {
  Object.defineProperty(type, 'def', {
    value: function value(def) {
      if (def === undefined && this['default'] === undefined) {
        this['default'] = undefined;
        return this;
      }
      if (!isFunction(def) && !validateType(this, def)) {
        warn(this._vueTypes_name + ' - invalid default value: "' + def + '"', def);
        return this;
      }
      this['default'] = isArray(def) || isPlainObject(def) ? function () {
        return def;
      } : def;

      return this;
    },
    enumerable: false,
    writable: false
  });
};

你可能感兴趣的:(vue.js,前端,javascript)