You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueJS中如何删除Vuetify数据表的选中行?

解决Vuetify数据表格结合Vuex删除选中行的问题

我来帮你搞定这个问题!首先得搞清楚为什么现在默认删最后一行:你调用deleteRow mutation的时候没有传递选中的行数据,导致mutation里的name参数是undefined,findIndex找不到匹配项就返回-1,而splice(-1, 1)刚好就是删除数组的最后一行——这就是问题根源!

接下来咱们分两步修改,实现只删除选中行的功能:

1. 修改Vue组件代码

咱们需要把选中的行数组传给Vuex的mutation,并且删除后清空选中状态:

<template>
  <div>
    <v-data-table
      v-model="selected"
      :headers="getHeaders"
      :items="getDesserts"
      hide-actions
      select-all
      item-key="name"
    >
      <template v-slot:headers="props">
        <tr>
          <th>
            <v-checkbox
              :input-value="props.all"
              :indeterminate="props.indeterminate"
              primary
              hide-details
              @click.stop="toggleAll"
            ></v-checkbox>
          </th>
          <th v-for="header in props.headers" :key="header.text">
            <v-icon small>arrow_upward</v-icon>
            {{ header.text }}
          </th>
        </tr>
      </template>
      <template v-slot:items="props">
        <tr :active="props.selected" @click="props.selected = !props.selected">
          <td>
            <v-checkbox
              :input-value="props.selected"
              primary
              hide-details
            ></v-checkbox>
          </td>
          <td>{{ props.item.name }}</td>
          <td>{{ props.item.calories }}</td>
          <td>{{ props.item.fat }}</td>
        </tr>
      </template>
    </v-data-table>
    <v-btn @click="deleteRow">Delete Selected</v-btn>
  </div>
</template>

<script>
import { mapGetters, mapMutations } from "vuex";

export default {
  name: "HelloWorld",
  data() {
    return {
      selected: []
    };
  },
  computed: {
    ...mapGetters({
      getHeaders: "getHeaders",
      getDesserts: "getDesserts"
    })
  },
  methods: {
    ...mapMutations({
      // 映射新的批量删除mutation
      deleteSelectedRows: "deleteSelectedRows"
    }),
    toggleAll() {
      if (this.selected.length) this.selected = [];
      else this.selected = this.getDesserts.slice();
    },
    deleteRow() {
      // 把选中的行数组传给mutation
      this.deleteSelectedRows(this.selected);
      // 删除后清空选中状态
      this.selected = [];
    }
  }
};
</script>

2. 修改Vuex Store代码

咱们需要把原来的单个删除mutation改成批量删除,通过选中项的name(因为表格的item-key是name)来过滤掉需要删除的行:

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    headers: [
      { text: "Dessert (100g serving)", align: "left", value: "name" },
      { text: "Calories", value: "calories" },
      { text: "Fat (g)", value: "fat" }
    ],
    desserts: [
      { value: false, name: "Lollipop", calories: 159, fat: 6.0 },
      { value: false, name: "Marshamallow", calories: 262, fat: 16.0 }
    ]
  },
  getters: {
    getHeaders: state => state.headers,
    getDesserts: state => state.desserts
  },
  mutations: {
    deleteSelectedRows(state, selectedItems) {
      // 提取所有选中项的name组成集合
      const selectedNames = selectedItems.map(item => item.name);
      // 过滤掉选中的行,生成新数组替换原数组(Vue会自动响应式更新)
      state.desserts = state.desserts.filter(dessert => !selectedNames.includes(dessert.name));
      
      // 如果你偏好原地修改数组(而不是生成新数组),可以用倒序splice的方式:
      // for (let i = state.desserts.length - 1; i >= 0; i--) {
      //   if (selectedNames.includes(state.desserts[i].name)) {
      //     state.desserts.splice(i, 1);
      //   }
      // }
    }
  }
});

为什么这么改?

  • 组件里通过v-model="selected"已经绑定了选中的行数组,我们只需要把这个数组传给Vuex的mutation就行
  • 批量删除时用filter生成新数组更符合Vuex的状态更新规范(也可以用倒序splice避免索引错乱)
  • 删除后清空selected数组,避免表格还保留之前的选中状态

内容的提问来源于stack exchange,提问作者user11606914

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 14:47:33