简洁
在公司实习,需要参与开发一个基于formily的低代码平台,实现自定义formily组件,在此记录一下。
示例源码
demo源码
实现思路
开始实现自定义组件之前最好先看一下formily官网的core、vue、element部分,如果有能力也可以阅读一下formily的源码,formily官网
项目搭建
在此不过多介绍如何搭建vue2的tsx项目,感兴趣可以看我的gitee示例
父组件中
- 父组件创建schema,在x-component中要调用我们自定义的组件,此处命名为"MyComponent",同时需要对其绑定数据
//部分数据代码
data:{
type:'object',
title:'商品',
'x-decorator':'FormItem',
//此处的MyComPonent就是自定义组件的名字
'x-component':'MyComponent',
'x-validator':{
required:true,
message:'请选择商品'
},
//枚举类型,因为自定义的组件中有下拉选择框
enum: [
{
label: "选项1",
value: '1'
},
{
label: "选项2",
value: '2'
},
{
label: "选项3",
value: '3'
}
],
}
},
- 其实对于父组件来说,使用MyComponent就像使用@formily/element的其他组件一样,只需要在x-component中使用,并且按照相关规范进行传值即可
const { SchemaField } = createSchemaField({
components: {
FormItem,
Input,
//一定要注意在此注册自定义组件!!!
MyComponent
},
})
- 完整代码
csdn里的markdown不支持显示tsx的代码,我就用CodeSnap进行贴图了,需要源码可以去仓库取
子组件(自定义组件)中
子组件是实现的关键,如果要深入了解原理等一定要去仔细看文档和源码,我也不是太了解
- 子组件主要是需要做到接收父组件的数据并能够返回数据,根据数据渲染样式,本自定义组件就是简单的实现一个输入框和一个下拉选择框
- 注意!对于表单来说,这个自定义组件是一个formItem,这也是自定义组件的意义,可以进一步根据需要扩充
- 主要代码如下
const MyComponent= Vue.extend({
name:'my-component',
props:{
value:{
type: Object as () => inputSelectType,
default:()=>({})
},
//下拉选择框的选项
options:{
type:Array as () => Array<optionType>
}
},
render(){
//贪图省事使用了组合式API里的ref,也可以使用watch进行实现数据动态变化
var newValue=ref(this.$props.value);
var {options}=this.$props;
return (
<div style={{display:'flex'}}>
<el-input v-model={newValue.value.price}></el-input>
<el-select v-model={newValue.value.goods} >
{options.map((option:optionType)=>(
<el-option label={option.label} value={option.value} key={option.value}></el-option>
))}
</el-select>
</div>
)
}
})
- 子组件中并没有schema,它只是实现自定义组件
- 由于子组件需要接收options进行选择框的传参,而formily的json schema中传的值的enum,因此需要做一个数据映射,使得子组件能接收到传来的enum的数据并转为options,实际上formily也是把enum映射为dataSource的
//连接到Formily表单系统
const FormItem = connect(
MyComponent,
//映射属性,将dataSource映射为options
mapProps(
{ dataSource: 'options', loading: true },
(props) => {
return {
...props,
}
},
)
)
以上就是一个简单的示例了,如果要问很深层次的原理我也不太懂