MST

星途 面试题库

面试题:Vue复杂表格组件插槽设计中作用域插槽的优化应用

对于一个复杂表格组件,使用作用域插槽来传递行数据进行自定义渲染。现在要求对其进行优化,以减少不必要的渲染开销。请阐述你的优化思路,并给出关键代码片段说明如何实现。
23.4万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

优化思路

  1. 数据缓存:缓存已渲染的数据,避免重复计算和渲染相同的数据。
  2. 条件渲染:仅在数据发生变化时进行渲染,减少不必要的渲染。
  3. 批量更新:将多次数据更新合并为一次,减少渲染次数。

关键代码片段

  1. 使用 computed 缓存数据
<template>
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <!-- 其他表头 -->
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) in cachedRows" :key="index">
        <td v-for="(cell, cellIndex) in row" :key="cellIndex">
          <slot :row="row" :cell="cell"></slot>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  data() {
    return {
      originalRows: [] // 原始行数据
    };
  },
  computed: {
    cachedRows() {
      return this.originalRows.map(row => {
        // 对每一行数据进行缓存处理,这里可根据实际需求进行数据处理
        return row;
      });
    }
  }
};
</script>
  1. 使用 watch 监听数据变化并进行条件渲染
<template>
  <table>
    <thead>
      <tr>
        <th>Column 1</th>
        <th>Column 2</th>
        <!-- 其他表头 -->
      </tr>
    </thead>
    <tbody v-if="shouldRender">
      <tr v-for="(row, index) in originalRows" :key="index">
        <td v-for="(cell, cellIndex) in row" :key="cellIndex">
          <slot :row="row" :cell="cell"></slot>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  data() {
    return {
      originalRows: [],
      shouldRender: true,
      previousRows: []
    };
  },
  watch: {
    originalRows: {
      deep: true,
      handler(newRows) {
        if (JSON.stringify(newRows) === JSON.stringify(this.previousRows)) {
          this.shouldRender = false;
        } else {
          this.shouldRender = true;
          this.previousRows = newRows;
        }
      }
    }
  }
};
</script>
  1. 批量更新数据(以 Vue 为例,使用 $nextTick
<template>
  <div>
    <button @click="batchUpdate">Batch Update</button>
    <table>
      <thead>
        <tr>
          <th>Column 1</th>
          <th>Column 2</th>
          <!-- 其他表头 -->
        </tr>
      </thead>
      <tbody>
        <tr v-for="(row, index) in originalRows" :key="index">
          <td v-for="(cell, cellIndex) in row" :key="cellIndex">
            <slot :row="row" :cell="cell"></slot>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      originalRows: []
    };
  },
  methods: {
    batchUpdate() {
      // 模拟多次数据更新
      const newRow1 = { /* 新数据1 */ };
      const newRow2 = { /* 新数据2 */ };
      this.$nextTick(() => {
        this.originalRows.push(newRow1);
        this.originalRows.push(newRow2);
      });
    }
  }
};
</script>