对页面列表的操作
1.书写前端页面(使用vue-cli,element-ui)
<div>
<el-row type="flex" class="row form1 info margin-top border" >
<el-col :span="24" >
<span><i class="el-icon-bottom blue"></i>明细品名和数据</span>
<el-button type="primary" class="btn " @click="add()">新增</el-button>
<el-button type="default" class="btn" @click="copy()">复制</el-button>
<el-button type="default" class="btn" @click="dialogFormVisible = true">
复制多行</el-button>
<!-- 对话框选择复制行数-->
<el-dialog title="复制多行" :visible.sync="dialogFormVisible">
<el-form >
<el-form-item label="复制行数" :label-width="120" >
<el-input v-model="lineNum" autocomplete="off" placeholder="请输入需要复制的行数"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="Copys()">确 定</el-button>
</div>
</el-dialog>
<el-button type="default" class="btn" @click="del()">删行</el-button>
<el-button type="default" class="btn" @click="delAll()">清空</el-button>
<el-button type="danger" class="btn" @click="CtrlV=true">批量粘贴</el-button>
<el-dialog
title="批量粘贴"
:visible.sync="CtrlV"
width="100%"
fullscreen
>
<span><el-input
autosize
type="textarea"
placeholder="请将需要复制的内容粘贴到这里"
v-model="textarea"
>
</el-input></span>
<span slot="footer" class="dialog-footer">
<el-button @click="CtrlV = false">取 消</el-button>
<el-button type="primary" @click="CtrlSure()">确 定</el-button>
</span>
</el-dialog>
</el-col>
</el-row>
<!-- <div v-show="isCopys"></div>-->
<el-row type="flex" class="row-bg info" style="height:55px">
<el-col :span="3" style="width: 164px;height:55px">
<div class="grid-content bg-purple border center" style="height: 55px">报关分提单号<i class="must-input">*</i></div>
</el-col>
<el-col :span="1" style="width: 106px;height:55px">
<div class="grid-content bg-purple border center" style="height: 55px">箱号<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width: 106px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">封号<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width: 94px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">箱型<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width: 256px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">英文品名<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width: 110px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">HsCode<i class="must-input">*</i>(10位)</div>
</el-col>
<el-col :span="1" style="width:80px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">件数<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width:114px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">包装单位<i class="must-input">*</i></div>
</el-col>
<el-col :span="2" style="width:80px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">毛重<i class="must-input">*</i>(KGS)</div>
</el-col>
<el-col :span="2" style="width:80px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">体积<i class="must-input">*</i>(CBM)</div>
</el-col>
<el-col :span="1" style="width:80px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">唛头</div>
</el-col>
<el-col :span="2" style="width:100px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">UN Code(危)</div>
</el-col>
<el-col :span="2" style="width:60px;height: 55px">
<div class="grid-content bg-purple border center" style="height: 55px">类别(危)</div>
</el-col>
</el-row>
<div>
<!-- {{items}}-->
<el-row class="row" type="flex" v-for="(item,index) in items" @click.native="checkRow(item,index)" :class="{active:currentIndex === index}" :key="index">
<el-col :span="3" style="width: 164px" class="border" >
<el-input v-model="item.billsNo" type="text" class=" enterIt" size=20 :class="{active:currentIndex === index}" @keyup.enter.native="focusNextInput(5+index*10)" />
</el-col>
<el-col :span="1" style="width: 106px" class="border" >
<el-input v-model="item.ctnNo" type="text" class="enterIt" size=20 @change="test(index)" :class="{active:currentIndex === index}" @keyup.enter.native="focusNextInput(6+index*10)" />
</el-col>
<el-col :span="2" style="width: 106px" class="border" >
<el-input v-model="item.title" type="text" class="enterIt" size="20" @change="test(index)" :class="{active:currentIndex === index}" @keyup.enter.native="focusNextInput(7+index*8)" />
</el-col>
<el-col :span="2" style="width: 94px" class="border">
<el-autocomplete
class="inline-input"
v-model="item.boxPile"
:fetch-suggestions="querySearchBox"
@select="handleSelectBox"
size=200
@change="isRight(item)"
@blur="test(index)"
:class="{active:currentIndex === index}"
></el-autocomplete>
</el-col>
<el-col :span="2" style="width: 256px" class="border">
<el-input v-model="item.englishName" type="text" class="enterIt" @click="test(index)" size=20 :class="{active:currentIndex === index}" @keyup.enter.native="focusNextInput(8+index*8)" />
</el-col>
<el-col :span="2" style="width: 110px" class="border">
<el-input v-model="item.hsCode" type="text" maxlength="10" class="enterIt" size=20 :class="{active:currentIndex === index}" @blur="isHSCode(item)" @keyup.enter.native="focusNextInput(9+index*8)" />
</el-col>
<el-col :span="1" style="width: 80px" class="border">
<el-input v-model="item.number" type="text" class="enterIt" size=20 :class="{active:currentIndex === index}" @blur="isNum(item,index)" @keyup.enter.native="focusNextInput(10+index*8)" />
</el-col>
<el-col :span="2" style="width:114px" class="border">
<el-autocomplete
class="inline-input"
v-model="item.packageUnit"
:fetch-suggestions="querySearch"
@select="handleSelect"
size=200
></el-autocomplete>
</el-col>
<el-col :span="2" style="width: 80px" class="border" :key="index">
<el-input v-model="item.kgs" type="text" class="enterIt" @blur="test(index)" size=20 :class="{active:currentIndex === index}" @change="isWeight(item)" @keyup.enter.native="focusNextInput(11+index*8)" />
</el-col>
<el-col :span="2" style="width: 80px" class="border">
<el-input v-model="item.cbm" type="text" class="enterIt" :class="{active:currentIndex === index}" @blur="isVolume(item)" size=20 @keyup.enter.native="focusNextInput(12+index*8)" />
</el-col>
<el-col :span="1" style="width: 80px" class="border">
<input v-model="item.tips" type="text" class="input" :class="{active:currentIndex === index}"/>
</el-col>
<el-col :span="2" style="width: 100px" class="border">
<input v-model="item.unCode" type="text" class="input" :class="{active:currentIndex === index}" />
</el-col>
<el-col :span="2" style="width: 60px" class="border">
<input v-model="item.category" type="text" class="input" :class="{active:currentIndex === index}" />
</el-col>
</el-row>
</div>
写出来之后页面基本就是这样。
2.功能讲解
2.1选中当前行
1.对每一个el-input需要使用v-model绑定
items: [{
billsNo: '',
ctnNo: '',
title: '',
boxPile: '',
englishName: '',
hsCode: '',
number: '',
packageUnit: '',
kgs: '',
cbm: '',
tips: '',
unCode: '',
category:'',
}],
注:因为这个不是表格,所以需要点击一格的时候选中该行数据,这样可以在指定位置新增复制删除
1.return中绑定一个数据,用来展示当前行
//选中当前行
currentIndex:0,
2.在代码开头,大家可以清楚看到v-for遍历了数组items,将索引index和值item给了这一行input框,通过点击事件传递这一行input框中的索引触发方法checkRow`,然后通过currentIndex绑定class来修改这一行的样式,区别没选中的行
// 选中一行数据
checkRow(item,index){
this.currentIndex=index;
},
css样式
.active{
background-color: rgb(239,238,151)
}
这下选中行就有不同的样式了,因为el-input里面有el-inner-input,所以外层的样式修改不影响内部框,所以写了3个input给大家展示
2.2新增
点击触发方法add(),通过splice在指定位置新增,splice三个参数,第一个索引,第二个位置,0的话表示不删除,第三个需要增加的数据,详情可以查看
https://www.w3school.com.cn/jsref/jsref_splice.asp
add() {
this.items.splice(this.currentIndex+1,0,{
billsNo:this.cargo.billNo,
ctnNo:'',
title:'',
boxPile:'',
englishName:'',
hsCode:'',
number:'',
packageUnit:'',
kgs:'',
cbm:'',
tips: '',
unCode: '',
category: '',
})
},
2.3 删除
在之前的新增的基础上,删除也就变得格外简单,这里不过多解释
del() {
this.items.splice(this.currentIndex, 1);
},
2.4清空
这里也不过多解释
// 清空明细表后新增一行
delAll() {
this.items = [];
this.add();
},
2.5复制
// 复制一行
copy(){
this.items.splice(this.currentIndex+1,0,{
billsNo:this.items[this.currentIndex].billsNo,
ctnNo:this.items[this.currentIndex].ctnNo,
title:this.items[this.currentIndex].title,
boxPile:this.items[this.currentIndex].boxPile,
englishName:this.items[this.currentIndex].englishName,
hsCode:this.items[this.currentIndex].hsCode,
number:this.items[this.currentIndex].number,
packageUnit:this.items[this.currentIndex].packageUnit,
kgs:this.items[this.currentIndex].kgs,
cbm:this.items[this.currentIndex].cbm,
tips:this.items[this.currentIndex].tips,
unCode:this.items[this.currentIndex].unCode,
category:this.items[this.currentIndex].category,
})
}
,
注:这里也许有人会用,this.items[this.currentIndex+1]=this.items[this.currentIndex],
把上一行的值给下一行,这样是不行的,这种是浅拷贝。而上面的截图是深拷贝
深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。
深浅拷贝原理:
假设B复制了A,修改A的时候,看B是否发生变化:
如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)
浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,
使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
详情可查看https://www.cnblogs.com/shakinghead/p/7651502.html
2.6复制多行
复制多行和复制单行是一样的
点击复制多行,弹出一个对话框
注:return中需要绑定dialogFormVisible:false,
(需要复制的行数)lineNum:0
isNaN用来判断是否是数字!
// 复制多行
Copys(){
let RowNum=isNaN(this.lineNum)
if(RowNum){
this.lineNum='';
this.$alert('请输入数字', '复制行数:错误提醒', {
confirmButtonText: '确定',
});
}
else{
for(let i=0;i<this.lineNum;i++){
this.copy()
}
this.dialogFormVisible=false;
this.lineNum='';
}
},
2.7批量粘贴
这边的批量粘贴是把excel表格中的内容复制过来,粘贴到页面中
同样是弹出一个对话框,把excel表格数据复制到对话框中的textarea中,
// 批量粘贴
CtrlSure(){
// alert(this.textarea);
// this.items=[];
// 清空元素
this.items.splice(0,this.items.length);
// 分成多行
let rows = this.textarea.split("\n");
for(let i=0;i<rows.length;i++){
// console.log(rows[i]);
if(rows[i]!==''){
//分成多列
let columns = rows[i].split("\t");
let dataColumns={};
for(let j=0;j<columns.length;j++){
// console.log(columns[j]);
// Ctrl就是和items相同的,因为触发这个函数的时候把items清空了,所以定义了一个Ctrl通过Object.keys来获取key值来进行新增操作
let keys=Object.keys(this.Ctrl[0]);
// console.log(keys);
// 这段代码的意思是给对象赋值
dataColumns[keys[j]]=columns[j];
// console.log(dataColumns);
}
this.items.push(dataColumns);
}
}
// this.textarea='';
this.CtrlV=false;
},
2.8按下回车进行下一格input框
大家可以找上面截图这一行代码
// 按下回车进入下一格
focusNextInput(num) {
// alert(1)
// alert(num);
let inputArray = document.getElementsByClassName("enterIt" ); //通过class去获取
// alert(inputArray.length)
let nextInput = inputArray[num+1].childNodes;
nextInput[1].focus();
},
因为el-input下面有子元素el-inner-input,所以使用了childNodes
给每个input框定一个值,我这边用了5+index10,是因为我之前有一些input框了,10是因为我给了这一行input框的前10格使用了回车下一格,通过index10可以在新增一行或者多行input框中的时候使用回车
如果你是在一个这样的列表input框之后后面还有input框,那就需要先获取这个input框中有几行,我这边就是num=this.item.length10+16
好了,今天就到这里了,如果对你有用的话支持一下博主