描述
需求
在表格里面渲染form表单,数字保留2位小数,不足的自动补齐。
选用
选用的是 iview 的组件 Form 、Input、Table。
Form表单的数据可以双向绑定,这样在对输入的数据做补零操作后,更新Form表单的model绑定的数据,即可更新。
没有使用 InputNumber 是因为它的交互用户体验不是很友好,而选用了常用的Input。
但问题不是出在这里,请继续往下看。
form+table
test.vue
<template>
<div>
<Form
ref="formTable"
:model="formTable"
:rules="rulesTable"
inline
>
<Table border :columns="columns" :data="data"></Table>
</Form>
</div>
</template>
<script>
let Trim=function(str,isGlobal) {
let result;
result = str.replace(/(^\s+)|(\s+$)/g,"");
if(isGlobal === true)
result = result.replace(/\s/g,"");
return result;
};
import FormItemInput from './form-item-input.vue';
export default {
name:'test',
components: {FormItemInput},
data() {
return {
//+++ form 表单 start
formTable:{},
rulesTable:{},
//+++ form 表单 end
// +++++++ table start
data:[
{
"id":1,
"name":"张三",
"score":""
},
{
"id":2,
"name":"李四",
"score":""
}
],
columns:[
{
title: '序号',
type: 'index',
width: 60,
align: 'center'
},
{
title: '姓名',
key: 'name',
width: 200,
ellipsis:true
},
{
title: '成绩',
key: 'score',
width: 150,
className:'custom-table-form',
ellipsis:true,
renderHeader:(h, params) => {
// 2019年1月4日11:01:36
// 必填 需要展示 *
return h('div', [
h('i', {
style: {
color: 'red',
marginRight: '5px'
}
}, '*'),
h('span', {}, params.column.title)
]);
},
render:(h, params)=>{
console.log('行数据',params.index, params);
/**
* 2019年5月14日17:08:32 添加校验
*/
let _formKey=params.column.key+'_'+params.row.id;
this.rulesTable[_formKey]=[];
// 2019年6月6日11:09:32 这步会导致,数据渲染两遍
this.$set(this.$data.formTable, _formKey,
params.row[params.column.key]===undefined || params.row[params.column.key]===null ? '' : params.row[params.column.key]);
this.rulesTable[_formKey].push(
{
/**
* 清掉input输入的空格,如果为空,不能通过
*/
validator(rule, value, callback, source, options) {
let errors = [];
if (!Trim(value) ){
errors.push(
new Error(
"该项是必填项"));
}
callback(errors);
}, trigger: 'blur'
},
{
validator(rule, value, callback, source, options) {
let errors = [];
// 正则控制范围,比较大小,同时存在才为true
let _tmpValue= value && Number(value);
// 可以出现一项:100分,或者n项 几分~几十分
let reg= /^([1-9]?[0-9]{1,2})?\0?(\.\d{1,2})?$/;
if(!(reg.test(_tmpValue)&&0<=_tmpValue&&_tmpValue<=100))
{
errors.push( new Error("请输入0-100之间的数字,小数点后最多允许保留2位小数") );
}
callback(errors);
},type:'string', trigger: 'blur'
}
);
return h(FormItemInput, {
props:{
formTable:this.formTable,
formKey:_formKey,
},
on:{
'on-form-blur':(value)=>{
// 更新提交数据
this.$refs.formTable.validateField(_formKey, (message)=>{
//2019年5月16日10:12:08 校验通过以后,保留2位小数
if(message.length==0)
{
this.formTable[_formKey]=Number(value).toFixed(2);
console.log('formTable',this.formTable);
}
});
}
}
});
}
},
],
// +++++++ table end
};
},
mounted() {
},
methods: {}
}
</script>
form-item-input.vue
<template>
<Form-item :prop="formKey" @on-form-blur="onFormBlur" :required="required" :label="label"
:setLengthNumber="setLengthNumber" :lastFormItem="lastFormItem">
<Input v-model="formTable[formKey]" ></Input>
</Form-item>
</template>
<script>
export default {
props:{
required:{
type:Boolean,
default:false
},
label:{
type:String,
default:''
},
formTable:Object,
formKey:String,
},
methods: {
onFormBlur(value){
this.$emit('on-form-blur', value);
}
}
}
</script>
图示
问题
使用 this.$set(this.$data.formTable, _formKey, '')
处理数据可以实现数据的双向绑定。
但是会导致表格渲染两次。
解决
怎么解决呢????
注意
此处的Form表单和表格的样式等需要调整细节,不在本次的重点,可以忽略。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。