文章目录
-
- 需求原因
- 实现过程
需求原因
在我们的后台管理项目中,需要显示数据。普通的文本显示和一些需要操作的数据。需要操作的数据列多了。不可避免的会使得我们的浏览器渲染这些大体量的数据会导致卡顿。近期项目中就遇到了这个问题。刚开始不是那么明显。但是数据多了之后。这个问题就更明显了。下拉滚动都会特别卡。
(案例)
(优化后)
实现过程
1.在我前面的文章中已经封装过了tab表格。此实现就是在原来封装的组件当中实现,我就把一些需要应用的表格编辑的 文本 下拉。
<el-tablev-if="TabKys"class="singleTableRef"ref="singleTableRef":data="getTables(PropTableS.tables)":show-summary="PropTableS.summary":summary-method="getSummaries"v-loading="Tablloading"border:highlight-current-row="false"@selection-change="handleSelectionChange"@cell-click="handelCellClick":row-style="{ height: '45px' }"row-key="id":expand-row-keys="PropTableS.expandChildren":header-cell-style="{ background: '#f0f2f7' }":scrollbar-always-on="true":default-sort="{ prop: 'date', order: 'descending' }":max-height="PropTableS.TableHeigth || 500":height="PropTableS.TableHeigths || PropTableS.TableHeigth"><template v-for="(child, key,index) in TabKys"><!-- 输入框 child.type是页面传递过来的表格列数据(列名、绑定的数据字段名、宽度)等信息 rowTableData:自定义存入的表格每行的数据信息(用户来点击处理行的编辑,显示原来的(输入框、下拉等操作)) [scope.row.index] :点击的哪一行 ([.index] :代表的坐标 0,1...) [index]:(当前的key).type:类型('input':输入框 'select':下拉框) --><template v-else-if=" rowTableData[scope.row.index][index].type == 'input' || child.type == 'input' "><!-- evalExpression :判断传递过来的isinput是否成立 --><span v-if="child.isinput == undefined ||evalExpression(scope.row, child.isinput, proxy.$route.meta.buts)"><el-inputv-if="rowTableData[scope.row.index][index].BorderDashed"v-model="scope.row[key]"@focus="HandelTextareaFocus(scope.row, key)"@blur="HandelTextareaBlur(scope.row, key,scope.row.index,index)"size="small":ref="`el_getforus_${scope.row.index}`":placeholder="child.placeholder"class="tab_input"type="input"/><!-- Border_Updata_Dashed_Click :span是带虚线边框的text 点击后显示原来的操作列 --><span v-else @click="Border_Updata_Dashed_Click(scope.row.index,index)" class="DashedBorderClass">{{scope.row[key]}}</span></span><span v-else><!-- 显示的text数据 这个只是普通的显示 -->{{ scope.row[key] }}</span></template><!-- 普通下拉 --><!-- 如上 --><template v-else-if=" rowTableData[scope.row.index][index].type == 'select' || child.type == 'select' "><el-selectv-if="rowTableData[scope.row.index][index].BorderDashed"style="width: 100px":filterable="true"@change="handelSelect(scope.row, key)"v-model="scope.row[key]"size="small"><el-optionv-for="(item, index) in child.children":key="index":label="item.label":value="item.value"/></el-select><span v-else @click="Border_Updata_Dashed_Click(scope.row.index,index)" class="DashedBorderClass">{{ isNaN(Number(scope.row[key])) == true ? scope.row[key] != undefined ? /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi.exec(scope.row[key]) ? scope.row[key] : scope.row[`${key.slice(0,key.lastIndexOf("_"))}`] : '' : '' }}</span></template></template></el-table><script setup lang="ts">
const tables = reactive([])
//存放每行的表头信息 每个操作列中每行的数据都存在这里,根据判断来独立显示哪行的操作列需要显示。(没有独立开,点击一行,所有行的操作列都显示出来了。)
let rowTableData = reactive({})//处理函数
function getTables(data: any) {
//props.PropTableS.tables 页面传递过来的表格显示数据.if(props.PropTableS.tables != undefined){if(props.PropTableS.tables.length > 0){props.PropTableS.tables.map((item,index) =>{let list = []for (const key in props.PropTableS.keyS) {list.push(props.PropTableS.keyS[key])}//为每行数据添加坐标(后面获取坐标来判断点击的哪个行)item['index'] = index//拷贝list 不然点击某个操作,所有的也会显示rowTableData[index] = JSON.parse(JSON.stringify(list)) })}}return props.PropTableS.tables;
}//输入框鼠标失去焦点
function HandelTextareaBlur(row: object, key: string,row_index:number,index:number) {//取消显示操作 (失去焦点,显示 待虚线的text文本)rowTableData[row_index][index].BorderDashed = false
}//鼠标点击
function Border_Updata_Dashed_Click(row_index:number,index:number){//跟上面失去焦点相反rowTableData[row_index][index].BorderDashed = true
}//点击单元格(点击table中任意单元格 获取该单元格的信息),此方法处理点击不是操作列的单元格,将会隐藏掉之前显示的操作列。显示带虚线的文本
function handelCellClick(row: any, column: any, cell: HTMLTableCellElement, event: Event){//判断点击的单元格是否包含type: 操作列的属性if(props.PropTableS.keyS[column.property].type == undefined){//循环rowTableData(存放每行的数据)Object.keys(rowTableData).map(item=>{rowTableData[item].map(c_item=>{if(c_item.title != undefined && c_item.type != undefined){//如果该行中包含 一下操作列if( ['input','select','shengSelect','shiSelect'].some(s_item=> s_item == c_item.type)){//全部隐藏操作列,显示带边框的文本c_item.BorderDashed = false}}})}) }
}
传递的数据类型上几篇文章中出现过。就不写了。这个只是代码片段,只处理此问题情况