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

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

相关推荐
桂月二二4 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
CodeClimb5 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
沈梦研5 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb5 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角5 小时前
CSS 颜色
前端·css
轻口味6 小时前
Vue.js 组件之间的通信模式
vue.js
九酒6 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae
浪浪山小白兔7 小时前
HTML5 新表单属性详解
前端·html·html5
lee5767 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm