首页 > 解决方案 > Vuetify:数据表槽值切换另一个槽值

问题描述

我正在使用 Vuetify 数据表,并且在其中两列上使用v-slot:item来插入开关

<v-data-table
  :headers="headers"
  :items="records"
  :search="search"
  :items-per-page="5"
>
  <template v-slot:item.monitor="{ item }">
    <v-switch v-model="item.monitor" color="success"></v-switch>
  </template>
  <template v-slot:item.manage="{ item }">
    <v-switch v-model="item.manage" color="success"></v-switch>
  </template>
</v-data-table>

我想要做的是将开关设置为项目组,以便一次只能选择一个(打开),但两者都可以是错误的(关闭)。所以只有一个可以有真正的价值。

在此处输入图像描述

我已经尝试使用Item Group 组件并让它工作,但我不确定它是否可以按照我想要的方式在表格中,因为这两个开关位于不同的插槽中。我的印象是v-item应该是兄弟组件,所以这让我认为这不适用于这种情况。

标签: vue.jsvuexvuetify.js

解决方案


在我看来,这个问题有两种不同的方法。您可以:

  • 观察records数组以检测其中一个对象的任一属性monitormanage属性的变化。
  • 不要v-model在开关上使用指令,而是提供只读值,然后在单击时手动更改它。

我更喜欢第二种选择。你可以这样做:

模板部分

<div id="app">
  <v-app id="inspire">
    <v-data-table :headers="headers" :items="records">
      <template v-slot:item.monitor="{ item }">
        <v-switch
          :input-value="item.monitor"
          readonly
          color="success"
          @click.stop="setSwitchesForItem(item.id, 'monitor', !item.monitor)"
        />
      </template>
      <template v-slot:item.manage="{ item }">
        <v-switch
          :input-value="item.manage"
          readonly
          color="success"
          @click.stop="setSwitchesForItem(item.id, 'manage', !item.manage)"
        />
      </template>
    </v-data-table>
  </v-app>
</div>

这里有几点需要注意:

  • v-model已被替换为:input-value
  • 已设置只读道具
  • 点击事件调用自定义方法。由于此处记录的错误,它需要.stop后缀

脚本部分

export default {
  // ...
  data() {
    return {
      headers: [
        { text: "Name", value: "name" },
        { text: "Monitor", value: "monitor" },
        { text: "Manage", value: "manage" }
      ],
      records: [
        {
          id: 1,
          name: "Item 1",
          monitor: true,
          manage: false
        },
        {
          id: 2,
          name: "Item 2",
          monitor: false,
          manage: true
        },
        {
          id: 3,
          name: "Item 3",
          monitor: false,
          manage: false
        }
      ]
    };
  },
  methods: {
    setSwitchesForItem(itemId, attributeName, attributeValue) {
      const record = this.records.find(r => r.id === itemId);
      // In case the new value is true, we need to make sure the other one is set to false
      if (attributeValue) {
        record[attributeName === "monitor" ? "manage" : "monitor"] = false;
      }
      record[attributeName] = attributeValue;
    }
  }
}

链接到Codepen


推荐阅读