跳至主要內容

table中渲染select等组件卡顿问题

Mr.Chen开发日志项目总结大约 2 分钟约 488 字

table 中渲染 select 等组件卡顿问题
<template>
  <el-table
    class="table"
    :data="tableData"
    height="200"
    @cell-click="showSelect"
  >
    <el-table-column label="js" prop="js">
      <template #default="scope">
        <el-select
          :ref="el => getCellRef('js', scope && scope.$index, el)"
          v-if="
            tableShow[scope && scope.$index] &&
            tableShow[scope && scope.$index].jsShow
          "
          v-model="scope.row.js"
          @change="val => tableCellChange('js', scope && scope.$index, val)"
          placeholder=""
        >
          <el-option
            v-for="item in js"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-input
          v-else
          :value="getJsLabel(scope && scope.row && scope.row.js)"
          readonly
          suffix-icon="arrow"
        />
      </template>
    </el-table-column>
    <el-table-column label="字母" prop="letter">
      <template #default="scope">
        <el-select
          :ref="el => getCellRef('letter', scope && scope.$index, el)"
          v-if="
            tableShow[scope && scope.$index] &&
            tableShow[scope && scope.$index].letterShow
          "
          v-model="scope.row.letter"
          @change="val => tableCellChange('letter', scope && scope.$index, val)"
          placeholder=""
        >
          <el-option
            v-for="item in letter"
            :key="item.id"
            :label="item.label"
            :value="item.id"
          />
        </el-select>
        <el-input
          v-else
          :value="getLetterLabel(scope && scope.row && scope.row.letter)"
          readonly
          suffix-icon="arrow"
        />
      </template>
    </el-table-column>
    <el-table-column label="其他" prop="other">
      <template #default="scope">
        <el-select
          :ref="el => getCellRef('other', scope && scope.$index, el)"
          v-if="
            tableShow[scope && scope.$index] &&
            tableShow[scope && scope.$index].otherShow
          "
          v-model="scope.row.other"
          @change="val => tableCellChange('other', scope && scope.$index, val)"
          placeholder=""
        >
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-input
          v-else
          :value="getOtherLabel(scope && scope.row && scope.row.other)"
          readonly
          suffix-icon="arrow"
        />
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup>
import { nextTick, ref, reactive } from 'vue'
const options = [
  {
    value: 'Option1',
    label: 'Option1'
  },
  {
    value: 'Option2',
    label: 'Option2'
  },
  {
    value: 'Option3',
    label: 'Option3'
  },
  {
    value: 'Option4',
    label: 'Option4'
  },
  {
    value: 'Option5',
    label: 'Option5'
  }
]
const letter = [
  { id: 1, label: 'Option A', desc: 'Option A' },
  { id: 2, label: 'Option B', desc: 'Option B' },
  { id: 3, label: 'Option C', desc: 'Option C' },
  { id: 4, label: 'Option A', desc: 'Option A' }
]
const js = [
  {
    value: 'HTML',
    label: 'HTML'
  },
  {
    value: 'CSS',
    label: 'CSS'
  },
  {
    value: 'JavaScript',
    label: 'JavaScript'
  }
]
const tableData = ref([])
const tableShow = reactive({})
const getJsLabel = value => {
  let item = js.find(v => v.value === value) || {}
  return item.label
}
const getLetterLabel = value => {
  let item = letter.find(v => v.id === value) || {}
  return item.label
}
const getOtherLabel = value => {
  let item = options.find(v => v.value === value) || {}
  return item.label
}
const tableCellChange = (name, index, value) => {
  tableShow[index][`${name}Show`] = false
  tableData.value[index][name] = value
}
const showSelect = (row, column) => {
  const name = column.property
  const index = row.index
  tableShow[index][`${name}Show`] = true
  nextTick(() => {
    const ref = cellrefs.value[`${name}${index}`]
    ref && ref.toggleMenu()
  })
}
const cellrefs = ref({})
const getCellRef = (name, index, ref) => {
  cellrefs.value[`${name}${index}`] = ref
}
for (let i = 0; i < 300; i++) {
  tableShow[i] = {
    jsShow: false,
    letterShow: false,
    otherShow: false
  }
  tableData.value.push({
    index: i,
    js: '',
    letter: '',
    other: ''
  })
}
</script>
<style>
.el-table__header {
  margin: 0;
}
.el-table__body {
  margin: 0;
}
</style>
上次编辑于: