跳到主要内容

updateSchema设置控件属性

说明:通过 JS 增强的 updateSchema 方法,可以设置控件上支持的任意属性,实现只读、禁用、下拉树多选、回车/失焦事件等效果,也可以根据其他字段的值动态设置,适用于【单表和主表的字段】

语法​

this.updateSchema({ field: '字段名', componentProps: { 属性名: 属性值 } })
参数说明
field要设置的字段名
componentProps控件属性,控件(antd 组件)本身支持的属性都可以设置,包括 onXxx 形式的事件。每个控件支持哪些属性,以对应的 antd 组件文档为准(文本框对应 Input,下拉框对应 Select,下拉树对应 TreeSelect 等)

componentProps 有两种写法:

写法说明
对象 componentProps: { ... }属性值固定,设置一次即生效
函数 componentProps: ({ formModel }) => ({ ... })根据表单数据动态计算属性,表单任意字段值变化时自动重新计算

updateSchema 需要写在 loaded 的 this.$nextTick 中,确保表单渲染完成后再设置

示例1:下拉树设置多选​

online 表单的下拉树控件默认单选,设置 multiple 等属性即可开启多选,多选值以逗号拼接保存(如 id1,id2,id3),数据库字段长度需预留足够空间。根据父子勾选需求有三种写法:

属性效果
multiple: true选中项以 tag 样式展示,父子节点互不联动,只选中点击的节点
multiple: true, treeCheckAble: true显示复选框,勾选父节点自动勾选全部子节点,输入框中显示的是勾选到的子节点
multiple: true, treeCheckAble: true, treeCheckStrictly: true显示复选框,父子节点各自独立勾选,勾父节点不会带上子节点

以下代码中 tree_val 为下拉树字段名,请替换为自己表单中的字段名。

写法1:tag样式多选(父子不联动)​

loaded(){
this.$nextTick(()=>{
this.updateSchema({ field: 'tree_val', componentProps: { multiple: true } })
})
}
  • 表单效果:分别点击「山东省」和「青岛市」,两个节点都被选中

写法2:复选框多选(勾父带子)​

loaded(){
this.$nextTick(()=>{
this.updateSchema({ field: 'tree_val', componentProps: { multiple: true, treeCheckAble: true } })
})
}
  • 表单效果:只勾选「山东省」,其下的「济南市」「青岛市」自动勾选

写法3:复选框多选(父子独立)​

loaded(){
this.$nextTick(()=>{
this.updateSchema({ field: 'tree_val', componentProps: { multiple: true, treeCheckAble: true, treeCheckStrictly: true } })
})
}
  • 表单效果:勾选「山东省」,子节点不受影响

下拉树根据其他字段重新加载数据,请参考 js控制下拉树数据

示例2:绑定回车、失焦、聚焦等事件​

事件也是控件属性,按 onXxx 的形式写在 componentProps 中即可:

属性说明
onPressEnter在文本框中按下回车时触发
onFocus / onBlur输入框获得 / 失去焦点时触发
onKeydown输入框中按下任意键时触发,可通过 e.key、e.code 判断按键

回车事件​

在名称、数量文本框中按回车,把当前值写入备注字段。

loaded(){
this.$nextTick(()=>{
this.updateSchema({ field: 'title', componentProps: { onPressEnter: () => {
let v = this.getFieldsValue()
this.setFieldsValue({ remark: '【回车触发】名称=' + (v.title == null ? '' : v.title) })
} } })
this.updateSchema({ field: 'qty', componentProps: { onPressEnter: () => {
let v = this.getFieldsValue()
this.setFieldsValue({ remark: '【回车触发】数量=' + (v.qty == null ? '' : v.qty) })
} } })
})
}
  • 表单效果

聚焦、失焦事件​

名称框聚焦、失焦时把值写入备注,按键时在控制台输出按键信息;数量框失焦时把值写入备注。

loaded(){
this.$nextTick(()=>{
this.updateSchema({ field: 'title', componentProps: {
onFocus: (e) => { this.setFieldsValue({ remark: '【focus】当前值=' + e.target.value }) },
onBlur: (e) => { this.setFieldsValue({ remark: '【blur】最终值=' + e.target.value }) },
onKeydown: (e) => { console.log('【keydown】code=' + e.code + ' key=' + e.key) }
} })
this.updateSchema({ field: 'qty', componentProps: {
onBlur: (e) => { this.setFieldsValue({ remark: '【blur】数量框=' + e.target.value }) }
} })
})
}
  • 表单效果

1.回调请使用箭头函数,函数内的 this 才能调用 getFieldsValue、setFieldsValue 等表单方法

2.事件参数 e 为原生事件对象,可通过 e.target.value 获取输入框当前值

3.值改变事件不需要用 updateSchema,直接使用 onlChange 即可,所有控件都支持,详见 表单值改变事件;onlChange 每次值变化都会触发,onBlur 只在离开输入框时触发一次,适合输入完成后再校验或查询

示例3:根据条件设置只读​

componentProps 写成函数,参数 formModel 为当前表单的实时数据,formModel.字段名 可获取任意字段的当前值。

场景:性别为「女」时,名称不允许修改;性别为「女」并且数量大于 10 时,备注不允许修改。

loaded(){
this.$nextTick(()=>{
// 性别为女(2)时,名称只读
this.updateSchema({ field: 'title', componentProps: ({ formModel }) => ({
readonly: formModel.sex == '2'
}) })
// 性别为女(2) 并且 数量大于10 时,备注只读
this.updateSchema({ field: 'remark', componentProps: ({ formModel }) => ({
readonly: formModel.sex == '2' && Number(formModel.qty) > 10
}) })
})
}
  • 表单效果

1.函数写法会在表单值变化时自动重新计算,不需要再额外写 onlChange;编辑页面打开时也会按已有数据自动计算

2.条件可以组合多个字段;返回对象中也可以同时设置多个属性,例如 ({ readonly: 条件, placeholder: 条件 ? '不可修改' : '请输入' })

3.把 readonly 换成其他属性(如 disabled),即可实现按条件禁用等效果

设置的属性必须是该控件支持的,不支持的属性不会生效。例如 readonly 只对文本框、多行文本等输入类控件有效,下拉、单选、日期等控件需要改用 disabled;字段显示隐藏请参考 字段显隐与禁用