在一个项目开发时,经常用到input组件或者textarea组件,当前项目使用的时[email protected]。提交测试时,测试人员反馈AInput和ATextarea组件没有限制字符长度导致保存时数据库插入报错,因此需要在前端需要限制字符长度。由于项目已经开发过半,因此想通过使用设置默认值方式设置maxLength属性。
再main.js文件中增加代码
import Antd, { Input } from "ant-design-vue";
Input.props.maxLength.default = 64;
然后手动再将每个ATextarea单独增加:max-length="200"
src\main.js
import Antd, { Input } from "ant-design-vue";
Input.props.maxLength.default = 64;
Input.TextArea.props.maxLength.default = 200;
运行结果
结果发现AInput和ATextarea组件的maxlength都变成了200
原因查找
\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
});
};