【问题标题】:Dynamic editable columns with vuetify data table带有 vuetify 数据表的动态可编辑列
【发布时间】:2022-07-04 21:48:24
【问题描述】:

我正在尝试制作一个 vue 数据表组件,我想制作它,以便如果您传递一个列名数组,这些列中的值将像 this example 中一样可编辑。我目前正在尝试循环传递给组件的数组道具,就像这样......

<template
   v-for="(column, index) in editableColumns"
   v-slot:[getEditableColumn(column)]="props"
>
    <v-edit-dialog
       :return-value.sync="props.item.desk"
       @save="save"
       @cancel="cancel"
       @open="open"
       @close="close"
       :key="index"
    >
          {{ props.item.desk }}
        <template v-slot:input>
            <v-text-field
              v-model="props.item.desk"
              label="Edit"
              single-line
              counter
            ></v-text-field>
        </template>
    </v-edit-dialog>
</template>

get 可编辑列的操作如下:

getEditableColumn(column) {
   console.log(column);
   return `item.${column}`;
},

它基本上返回我想要编辑的列的值item.columnName 但该函数永远不会运行,我必须提到,如果我直接传递这样的名称而不使用 for 循环它可以工作,但我希望它能够动态工作,因为我将在多个位置使用具有不同列名的表,并且我不想让它们所有列都可编辑。

下面我附上了组件的完整代码。

<template>
  <v-card>
    <v-card-title>
      {{ title || "" }}
      <v-col>
        <v-btn icon color="black" v-if="refresh">
          <v-icon>mdi-refresh</v-icon>
        </v-btn>
        <v-btn icon color="black" v-if="exportExcel" @click="exportToXlsx">
          <v-icon>mdi-microsoft-excel</v-icon>
        </v-btn>
        <v-btn icon color="black" v-if="exportPdf">
          <v-icon>mdi-file-pdf-box</v-icon>
        </v-btn>
        <v-btn icon color="black" v-if="fontSizeControlls">
          <v-icon>mdi-format-font-size-decrease</v-icon>
        </v-btn>
        <v-btn icon color="black" v-if="fontSizeControlls" @click="logSelected">
          <v-icon>mdi-format-font-size-increase</v-icon>
        </v-btn>
      </v-col>
      <v-spacer></v-spacer>
      <v-col v-if="searchBar">
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          outlined
          dense
        ></v-text-field>
      </v-col>
    </v-card-title>
    <v-data-table
      @input="(selected) => $emit('selected', selected)"
      @click:row="rowClickFunction"
      v-model="selected"
      :headers="headers"
      :items="data"
      :search="search"
      :show-select="showSelect"
      :single-select="singleSelect"
      :height="height"
      :items-per-page="itemsPerPage"
      :item-key="itemKey"
      dense
    >
      <!-- Pass template elements inside the component call to render custom components inside the table -->
      <template
        v-for="slot in Object.keys($scopedSlots)"
        :slot="slot"
        slot-scope="scope"
      >
        <slot :name="slot" v-bind="scope" />
      </template>
      <template
        v-for="(column, index) in editableColumns"
        v-slot:[getEditableColumn(column)]="props"
      >
        <v-edit-dialog
          :return-value.sync="props.item.desk"
          @save="save"
          @cancel="cancel"
          @open="open"
          @close="close"
          :key="index"
        >
          {{ props.item.desk }}
          <template v-slot:input>
            <v-text-field
              v-model="props.item.desk"
              label="Edit"
              single-line
              counter
            ></v-text-field>
          </template>
        </v-edit-dialog>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
import { utils, writeFile } from "xlsx";

export default {
  props: {
    headers: Array,
    data: Array,
    title: String,
    height: String,
    itemsPerPage: Number,
    itemKey: String,
    searchBar: { tpye: Boolean, default: false },
    rowClickFunction: {
      type: Function,
      default: () => {},
    },
    editableColumns: {
      type: Array,
    },
    refresh: {
      type: Boolean,
      default: false,
    },
    exportExcel: {
      type: Boolean,
      default: false,
    },
    exportPdf: {
      type: Boolean,
      default: false,
    },
    fontSizeControlls: {
      type: Boolean,
      default: false,
    },
    singleSelect: {
      type: Boolean,
      default: false,
    },
    showSelect: {
      type: Boolean,
      default: false,
    },
    xlsxName: {
      type: String,
      default: "Sheet.xlsx",
    },
  },
  data() {
    return {
      search: "",
      selected: [],
      dialog: false,
    };
  },

  methods: {
    exportToXlsx() {
      const worksheet = utils.json_to_sheet(this.data);
      const workbook = utils.book_new();
      utils.book_append_sheet(workbook, worksheet, "Data");
      writeFile(workbook, this.xlsxName);
    },

    getEditableColumn(column) {
      console.log(column);
      return `item.${column}`;
    },

    logSelected() {
      console.log(this.selected);
    },

    logRow(row) {
      console.log(row);
      console.log(this.selected);
    },

    getSlotName(slot) {
      return `${slot}.slotName`;
    },

    save() {
      this.snack = true;
      this.snackColor = "success";
      this.snackText = "Data saved";
    },
    cancel() {
      this.snack = true;
      this.snackColor = "error";
      this.snackText = "Canceled";
    },
    open() {
      this.snack = true;
      this.snackColor = "info";
      this.snackText = "Dialog opened";
    },
    close() {
      console.log("Dialog closed");
    },
  },
};
</script>

【问题讨论】:

    标签: vue.js vuejs2 vue-component vuetify.js


    【解决方案1】:

    插槽名称必须是 headers 元素的值之一

    【讨论】:

      猜你喜欢
      • 2013-02-23
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 2015-07-28
      • 2013-09-21
      • 1970-01-01
      相关资源
      最近更新 更多