前言
偶尔会遇到需要修改外部组件的问题,官方在维护的还好说,可以提一个isuse,但是进度就不好说了,另外遇到官方不维护的,就没法了 比如,我遇到的ant-design-vue 1.x 就不更新了
问题
我想要的功能其实比较简单,就是表单验证的时候,想支持一下value属性
现在是这样的形式,需要传prop属性,因为是数组循环,所以需要传 字段名+索引+name 很麻烦
<a-form-model-item :prop="'options.'+ index+ '.name'"
v-for="(item ,index) in form_data.options">
<a-input v-model="item.name"/>
</a-form-model-item>
<a-button>添加</a-button>
界面像这样的
期望写法, 传给form-model-item的是value,而不是字段名
<a-form-model-item :value="item.name"
v-for="(item ,index) in form_data.options">
<a-input v-model="item.name"/>
</a-form-model-item>
<a-button>添加</a-button>
看起来好像和prop写法没有很好的改进,但是看看这个界面,这样的输入框就很麻烦了
所以功能还是很有用的
解决
首先看看源码,代码还是比较简单的,就是修改fieldValue获取value的方式,可以看到默认就是只能在model里面取
修改逻辑也比较简单,就是增加2个参数判断
网上查到patch-package 这个包
看起来操作也比较麻烦,为了这么简单的功能也不必要,于是想一想能不能像继承类一下,覆盖一下代码
于是就想到把组件导出来,直接修改相关方法,
import {FormModel} from 'ant-design-vue';
//增加props选项
FormModel.Item.props.value = {
type:[String,Number,Boolean,Array,Object,Date,Function,Symbol]
};
FormModel.Item.props.use_value_verification = {
type:Boolean,
default:false,
};
//修改
FormModel.Item.computed.fieldValue = function fieldValue () {
var model = this.FormContext.model;
if (!model || !this.prop) {
return;
}
if(this.use_value_verification){
return this.value;
}
var path = this.prop;
if (path.indexOf(':') !== -1) {
path = path.replace(/:/g, '.');
}
return getPropByPath(model, path, true).v;
};
//使用修改后的组件
export default {
components:{
'a-form-model-item-fix':FormModel.Item,
},
}
运行后发现验证总是延迟一步,输入了值,还是报错
后面发现change事件比传值快,所以就加了一个延迟,但是不生效,就很奇怪了
FormModel.Item.methods.onFieldBlur =function () {
setTimeout(()=>{
this.validate('blur');
},1)
}
FormModel.Item.methods.onFieldChange = function () {
if (this.validateDisabled) {
this.validateDisabled = false;
return;
}
setTimeout(()=>{
this.validate('change');
},1);
}
最后发现import导入过来的组件有一个 _Ctor 属性,会缓存默认的函数,所以就过滤掉,用一个新的对象
let FormModelItemOptions = {};
for(let key in FormModel.Item){
if(key == '_Ctor'){
continue;
}
FormModelItemOptions[key] = FormModel.Item[key];
}
FormModelItemOptions.name = 'AFormModelItemFix';
export default {
components:{
'a-form-model-item-fix':FormModelItemOptions,
},
}
正常了
总结
对于这种小需求,还是自己动手来得快,哈哈~