共计 2970 个字符,预计需要花费 8 分钟才能阅读完成。
描述
需求
在表格里面渲染 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 表单和表格的样式等需要调整细节,不在本次的重点,可以忽略。
正文完