文章目录
需求原因
在我们的后台管理项目中,需要显示数据。普通的文本显示和一些需要操作的数据。需要操作的数据列多了。不可避免的会使得我们的浏览器渲染这些大体量的数据会导致卡顿。近期项目中就遇到了这个问题。刚开始不是那么明显。但是数据多了之后。这个问题就更明显了。下拉滚动都会特别卡。
(案例)
(优化后)
实现过程
1.在我前面的文章中已经封装过了tab表格。此实现就是在原来封装的组件当中实现,我就把一些需要应用的表格编辑的 文本 下拉。
<el-table
v-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-input
v-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-select
v-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-option
v-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
}
}
})
})
}
}
传递的数据类型上几篇文章中出现过。就不写了。这个只是代码片段,只处理此问题情况