修改第三方模块组件的方法

382 阅读2分钟

前言

偶尔会遇到需要修改外部组件的问题,官方在维护的还好说,可以提一个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>

界面像这样的

image.png

期望写法, 传给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写法没有很好的改进,但是看看这个界面,这样的输入框就很麻烦了

image.png

所以功能还是很有用的

解决

首先看看源码,代码还是比较简单的,就是修改fieldValue获取value的方式,可以看到默认就是只能在model里面取

image.png

修改逻辑也比较简单,就是增加2个参数判断

网上查到patch-package 这个包

www.npmjs.com/package/pat…

看起来操作也比较麻烦,为了这么简单的功能也不必要,于是想一想能不能像继承类一下,覆盖一下代码

于是就想到把组件导出来,直接修改相关方法,


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,
  },
  
}

运行后发现验证总是延迟一步,输入了值,还是报错

image.png

后面发现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,
  },
}

正常了

image.png

总结

对于这种小需求,还是自己动手来得快,哈哈~