JSON Forms数字字段输入1.报错、1.0自动删.0的解决方法问询
JSON Forms数字字段输入问题解决方案
问题概述
使用JSON Forms时遇到数字类型字段的两个核心问题:
- 输入
1.05这类数值过程中,输入到1.阶段会立即触发验证错误 - 输入
1.0后,.0部分会被自动格式化删除
尝试过调整AJV参数、移除AJV实例、修改@change钩子等操作,均未解决问题。需求是将验证/自动修正逻辑改为change事件触发(而非实时input触发),或找到其他可行方案。
相关代码配置
Forms组件
<json-forms :schema="schema" :uischema="null" :data="localData" :renderers="renderers" :ajv="ajv" @change="(evt) => localData = evt.data" />
Schema定义
{ "type": "object", "default": {}, "properties": { "nir": { "type": "number", "title": "NIR" }, "rgb": { "type": "number", "title": "RGB" } } }
AJV配置
ajv: Ajv = createAjv( { useDefaults: true, multipleOfPrecision: 2, } );
解决方案:自定义数字渲染器
JSON Forms默认数字组件会在input事件实时处理验证和值格式化,要修改触发时机,需自定义数字渲染器替换默认组件,将逻辑绑定到change事件(即输入框失去焦点时)。
1. 编写自定义数字渲染器(Vue版本)
<template> <div class="custom-number-control"> <label>{{ label }}</label> <input type="text" :value="displayValue" @change="onInputChange" :class="{ 'input-error': hasErrors }" /> <span v-if="hasErrors" class="error-text">{{ errorMessage }}</span> </div> </template> <script> import { rendererProps } from '@jsonforms/vue'; export default { name: 'CustomNumberRenderer', props: rendererProps, computed: { label() { return this.uischema.label || this.schema.title || ''; }, displayValue() { // 处理值显示:整数格式的数字强制显示为x.0,避免.0被自动删除 if (typeof this.data === 'number') { return Number.isInteger(this.data) ? `${this.data}.0` : String(this.data); } return ''; }, hasErrors() { return this.errors.some(err => err.path === this.path); }, errorMessage() { const fieldError = this.errors.find(err => err.path === this.path); return fieldError ? fieldError.message : ''; } }, methods: { onInputChange(e) { const inputVal = e.target.value.trim(); let newValue; // 处理输入为空的情况 if (!inputVal) { newValue = undefined; } // 处理输入以.结尾的情况,暂时转换为带0的小数(如"1."转为1.0) else if (inputVal.endsWith('.')) { newValue = parseFloat(`${inputVal}0`); } // 正常数字转换 else { newValue = parseFloat(inputVal); } // 触发JSON Forms的数据更新 this.handleChange(this.path, newValue); } } }; </script> <style scoped> .custom-number-control { margin-bottom: 1rem; } .input-error { border-color: #dc3545; } .error-text { color: #dc3545; font-size: 0.875rem; } </style>
2. 注册自定义渲染器
将自定义渲染器替换默认的数字渲染器,确保JSON Forms使用新组件:
import { vanillaRenderers } from '@jsonforms/vue-vanilla'; import CustomNumberRenderer from './CustomNumberRenderer.vue'; // 替换默认数字渲染器 export const renderers = [ ...vanillaRenderers, { tester: (schema, uischema, context) => { // 匹配数字类型的字段 return schema.type === 'number' ? 10 : -1; }, renderer: CustomNumberRenderer } ];
方案说明
- 验证与值更新逻辑绑定到
change事件,只有当输入框失去焦点时才会触发数据更新和验证,避免输入过程中出现错误提示 - 自定义值显示逻辑,强制整数格式的数字显示为
x.0,解决.0被自动删除的问题 - 处理输入
1.这类中间状态,自动补全为1.0后再转换为数字,既符合用户输入习惯,也满足schema的数字类型要求
内容的提问来源于stack exchange,提问作者TheSaGe
相关产品推荐
相关产品推荐

