描述
需求
在表格裏面渲染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表單和表格的樣式等需要調整細節,不在本次的重點,可以忽略。