Vue3:el-table组件存在多列操作数据,页面渲染导致进入页面卡顿问题优化。

文章目录

需求原因

在我们的后台管理项目中,需要显示数据。普通的文本显示和一些需要操作的数据。需要操作的数据列多了。不可避免的会使得我们的浏览器渲染这些大体量的数据会导致卡顿。近期项目中就遇到了这个问题。刚开始不是那么明显。但是数据多了之后。这个问题就更明显了。下拉滚动都会特别卡。

(案例)

(优化后)

实现过程

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
         }
        }
      })
   })  
  }
}

传递的数据类型上几篇文章中出现过。就不写了。这个只是代码片段,只处理此问题情况

相关推荐
升讯威在线客服系统几秒前
如何通过 Docker 在没有域名的情况下快速上线客服系统
java·运维·前端·python·docker·容器·.net
AsBefore麦小兜2 分钟前
Vite vs Webpack
前端·webpack
LaughingZhu3 分钟前
PH热榜 | 2025-02-23
前端·人工智能·经验分享·搜索引擎·产品运营
道不尽世间的沧桑2 小时前
第17篇:网络请求与Axios集成
开发语言·前端·javascript
diemeng11193 小时前
AI前端开发技能变革时代:效率与创新的新范式
前端·人工智能
bin91535 小时前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云7 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
曦月合一7 小时前
html中iframe标签 隐藏滚动条
前端·html·iframe
奶球不是球7 小时前
el-button按钮的loading状态设置
前端·javascript
kidding7237 小时前
前端VUE3的面试题
前端·typescript·compositionapi·fragment·teleport·suspense