目录
1、项目场景
场景一:输入数据时,不需要自动四舍五入,用户输入什么就显示什么。
场景二:多列、多行填写数据时,且重复数据多、校验多时,需要快速复制、粘贴数据。
2、问题描述
<el-input>或<el-input-number>输入数值时,会默认自动四舍五入,项目中遇到场景要求在保留位数前提下,用户输入什么就显示什么,真TM沃特法克!!!(^__^)
上面这种输入后,显示的值就不符合要求。
3、原因分析
element-ui 默认是四舍五入的。
4、场景一:解决方案
通过主要代码控制
blurInput方法 oninput ="this.value = this.value.replace(/[^-\d]/g, '')" @keyup.enter="handleEnter(scope.row.index)"对数据输入、enter、失焦进行控制,要考虑输入. .2 ..3 -2- -2-- 等情况。
确保输入三位小数时:例如3.887,输入3.8876,不会四舍五入,只显示3.887,且传给后端是3.887。
<template>
<el-table :data="tableData" ref="tableData" class="customer-table" @cell-click="tableDbEdit" :row-class-name="tableRowClassName">
<el-table-column label="序号" width="50px" type="index" header-align="center" align="center" class="custom-index-column" :resizable="false"/>
<el-table-column prop="packageMonth" label="月份" width="100px" show-overflow-tooltip align="center" header-align="center" :resizable="false"/>
<el-table-column label="常规数据" header-align="center" key="1" :sortable="false">
<el-table-column prop="u11" label="三位小数" min-width="80px" header-align="center" align="right" key="u11" :sortable="false">
<template scope="scope">
<el-input v-if="showInput == `u11${scope.row.index}`" v-model="scope.row.u11" placeholder=""
@blur='blurInput(scope.row.guid,"u11",scope.row.u11,"1",scope.row.packageMonth)' v-focus
oninput ="this.value=this.value.replace(/[^0-9.]/g,'')"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,3}/);" clearable></el-input>
<div v-else>{{ scope.row.u11 |thereRounding }}</div>
</template>
</el-table-column>
<el-table-column prop="commonPrice" label="两位小数" :sortable="false"
min-width="80px" key="commonPrice" header-align="center" align="right">
<template scope="scope">
<el-input v-if="showInput == `commonPrice${scope.row.index}`" v-model="scope.row.commonPrice" placeholder=""
@blur='blurInput(scope.row.guid,"commonPrice",scope.row.commonPrice,"3",scope.row.packageMonth)' v-focus
oninput ="this.value=this.value.replace(/[^0-9.]/g,'')"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/);" clearable></el-input>
<div v-else>{{ scope.row.commonPrice |twoRounding}}</div>
</template>
</el-table-column>
<el-table-column prop="commonPriceDifference" label="整数"
min-width="80px" key="commonPriceDifference" header-align="center" align="right" :sortable="false">
<template scope="scope">
<el-input v-if="showInput == `commonPriceDifference${scope.row.index}`" v-model="scope.row.commonPriceDifference" placeholder=""
@blur='blurInput(scope.row.guid,"commonPriceDifference",scope.row.commonPriceDifference,"2",scope.row.packageMonth)' v-focus
oninput ="this.value = this.value.replace(/[^-\d]/g, '')"
@keyup.enter="handleEnter(scope.row.index)" clearable></el-input>
<div v-else>{{ scope.row.commonPriceDifference|twoRounding }}</div>
</template>
</el-table-column>
<el-table-column :sortable="false" align="center" text-align="center" width="90" label="操作">
<template v-slot="scope">
<el-button type="text" @click="copy(scope.row)" style="font-size: 12px">复制</el-button>
<el-button type="text" @click="paste(scope.row)" style="font-size: 12px">粘贴</el-button>
</template>
</el-table-column>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: "index",
directives: {
// 通过自定义指令实现的表单自动获得光标的操作
//注意:唯一的主键guid不能一样,否则有错,光标无法点进去
focus: {
inserted: function (el) {
//debugger;
if (el.tagName.toLocaleLowerCase() == 'input') {
el.focus()
} else {
if (el.getElementsByTagName('input')) {
el.getElementsByTagName('input')[0].focus()
}
}
el.focus()
}
}
},
filters: {
// 保留2位小数
twoRounding(value) {
if (value != null && value !== '') {
return (value * 1).toFixed(2)
}
},
thereRounding(value) {
if (value != null && value !== '') {
return (value * 1).toFixed(3)
}
},
integerRounding(value) {
if (value != null && value !== '') {
return (value * 1).toFixed(0)
}
},
},
data() {
return {
showInput:'',
tableData: [{
"packageMonth": "一月",
"packageType": null,
"packageCategory": null,
"commonPrice": undefined,
"commonPriceDifference": undefined,
"greenPrice": undefined,
"greenPriceDifference": undefined,
"greenEnvironmentPrice": undefined,
"greenEnvironmentPricePay": undefined,
},{
"packageMonth": "二月",
"packageType": null,
"packageCategory": null,
"commonPrice": undefined,
"commonPriceDifference": undefined,
"greenPrice": undefined,
"greenPriceDifference": undefined,
"greenEnvironmentPrice": undefined,
"greenEnvironmentPricePay": undefined,
}
],
copyObject: {},//复制的内容
}
},
methods: {
tableRowClassName({row, rowIndex}) {
row.index = rowIndex
},
tableDbEdit(row, column, cell, event) {
this.showInput = column.property + row.index
console.log('this.showInput:' + this.showInput)
},
truncateDecimal(num, decimals) {
const parts = num.toString().split('.');
if (parts.length < 2) return num.toString(); // 如果没有小数部分,直接返回
parts[1] = parts[1].slice(0, decimals); // 截取小数点后的位数
return parts.join('.');
},
handleEnter(index,name) {
const inputValue = this.tableData[index].name;
if (isNaN(inputValue)) {
if (inputValue !== '' && inputValue !== '-') {
this.$set(this.tableData, `${index}.name`, ''); // 清空非数字且不是负号或空字符串时清空
}
} else {
// 确保输入的是整数,如果用户输入了小数则转换为整数
const parsedValue = parseInt(inputValue, 10);
if (parsedValue.toString() !== inputValue) {
this.$set(this.tableData, `${index}.name`, parsedValue);
}
}
},
async blurInput(id, name, value,flag,currMoth) { // 当input失去光标后进行的操作
// console.log("===1===>"+JSON.stringify(this.tableData))
if (value !== '' && value != null) {
this.tableData.forEach(item => {
if (item.packageMonth == currMoth) { //当月数据
if (value.toString().startsWith('.')) {
if (name == 'commonPrice' || name == 'greenPrice' || name == 'u11' || name == 'u12' || name == 'u21' || name == 'u22'
|| name == 'greenEnvironmentPrice' || name == 'greenEnvironmentPricePay') {//当以.开始置为null
value = null
item[name] = null
}
} else {
const firstDotIndex = value.toString().indexOf('.');
const secondDotIndex = value.toString().indexOf('.', firstDotIndex + 1);
let cleanedValue = value;
if (firstDotIndex !== -1 && secondDotIndex !== -1) { // 存在两个小数点,则保留第二个小数点前的所有信息
cleanedValue = value.substring(0, secondDotIndex);
}
if (cleanedValue !== value) {
value = cleanedValue;
}
if (flag == '1') { //保留三位 1—保留三位 2-保留整数 3-保留两位
item[name] = this.truncateDecimal(value, 3)
} else if (flag == '2') {
if (isNaN(Number(value)) || value == '') {//处理 输入- -2- -2--等情况
item[name] = null
} else {
item[name] = this.truncateDecimal(value, 0)
}
} else {
item[name] = this.truncateDecimal(value, 2)
}
}
}
})
}
this.showInput = ''
},
//复制文本内容
copy(row) {
this.copyObject = []
Object.keys(row).forEach(key => {
this.copyObject[key] = row[key]
})
// console.log("------2--------> "+JSON.stringify(row));
},
//粘贴文本内容
paste(row) {
var month = ''
var index = ''
for (let i = 0; i < this.tableData.length; i++) {
if (row.packageMonth === this.tableData[i].packageMonth) {
month = this.tableData[i].packageMonth //粘贴时,保持当前行的数据 月份和index不变
index = this.tableData[i].index
Object.keys(this.copyObject).forEach(key => {
this.$set(this.tableData[i], key, this.copyObject[key])
})
this.$set(this.tableData[i], "packageMonth", month) //先复制,再替换成原有的 月份 和 index
this.$set(this.tableData[i], "index", index)
}
}
},
}
}
</script>
<style scoped>
</style>
5、场景二:复制、黏贴功能
场景:
针对列比较多、或需求要复制、粘贴时。
主要源码
复制:定义变量、复制数据;
粘贴:对比数据、获取不需要改变的列的值、全部复制数据,还原不需要改变的列。
//复制文本内容
copy(row) {
this.copyObject = []
Object.keys(row).forEach(key => {
this.copyObject[key] = row[key]
})
// console.log("------2--------> "+JSON.stringify(row));
},
//粘贴文本内容
paste(row) {
var month = ''
var index = ''
for (let i = 0; i < this.tableData.length; i++) {
if (row.packageMonth === this.tableData[i].packageMonth) {
month = this.tableData[i].packageMonth //粘贴时,保持当前行的数据 月份和index不变
index = this.tableData[i].index
Object.keys(this.copyObject).forEach(key => {
this.$set(this.tableData[i], key, this.copyObject[key])
})
this.$set(this.tableData[i], "packageMonth", month) //先复制,再替换成原有的 月份 和 index
this.$set(this.tableData[i], "index", index)
}
}
},