根据计算 属性 对过滤后的 table 进行排序

sorting a filtered table as computed property

我有一个 md-table,我可以在其中按名称过滤行,当然,过滤器工作正常,但只要我点击列名,行就不会排序

你应该能够像在这个沙盒中一样对它们进行排序 https://codesandbox.io/s/n7l7o742qm?module=App.vue

但是如果你试试我的代码 https://codesandbox.io/s/vue-material-search-and-empty-state-forked-6bb48?file=/App.vue

排序功能将不起作用

HTML

<md-table
  v-model="filteredRepetitions"
  md-sort="corso"
  md-sort-order="asc"
  md-card
  md-fixed-header
>
  <md-table-toolbar>
    <h1 class="md-title">With auto select and alternate headers</h1>
    <md-field md-clearable class="md-toolbar-section-end">
      <md-input placeholder="Search by course..." v-model="search"/>
    </md-field>
  </md-table-toolbar>


  <md-table-row
    class="md-primary"
    slot="md-table-row"
    slot-scope="{ item }"
  >
    <md-table-cell md-label="Corso" md-sort-by="corso">{{ item.corso }}</md-table-cell>
    <md-table-cell md-label="Docente" md-sort-by="docente">{{ item.docente }}</md-table-cell>
    <md-table-cell md-label="Data" md-sort-by="timeSlot.data">{{ item.timeSlot.data }}</md-table-cell>
    <md-table-cell
      md-label="Fascia oraria"
      md-sort-by="timeSlot.fasciaOraria"
    >{{ item.timeSlot.fasciaOraria }}</md-table-cell>
    <md-table-cell md-label="Stato" md-sort-by="stato">{{ item.stato }}</md-table-cell>
  </md-table-row>
</md-table>

JS

const toLower = text => text.toString().toLowerCase();
export default {
    data() {
        return {
            search: '',
            repetitions2: [
                {
                    corso: 'Programmazione 3',
                    docente: 'Liliana Aridissono',
                    timeSlot: {
                        fasciaOraria: '15:00-16:00',
                        data: '2020-09-17'
                    },
                    stato: 'attiva'
                },
                {
                    corso: 'Python',
                    docente: 'Marco Amedura',
                    timeSlot: {
                        fasciaOraria: '17:00-18:00',
                        data: '2020-03-17'
                    },
                    stato: 'noattiva',
                },
                {
                    corso: 'Matematica Discreta',
                    docente: 'Vincenzo Bellomo',
                    timeSlot: {
                        fasciaOraria: '16:00-17:00',
                        data: '2020-02-17'
                    },
                    stato: 'noattiva',
                },
                {
                    corso: 'Algoritmi',
                    docente: 'Patti Viviana',
                    timeSlot: {
                        fasciaOraria: '16:00-17:00',
                        data: '2020-10-17'
                    },
                    stato: 'attiva',
                },
                {
                    corso: 'Analisi',
                    docente: 'Pinco Pallo',
                    timeSlot: {
                        fasciaOraria: '18:00-19:00',
                        data: '2020-10-26'
                    },
                    stato: 'attiva',
                }
            ]
        }
    },
    methods: {
    },
    computed: {
        filteredRepetitions: {
            get: function () {
                return this.repetitions2.filter(item => toLower(item.corso).includes(toLower(this.search)))
            },
            set: function (array) {
               // what should i say?
            }
        }
    },
}

奖金问题: 是否可以不只针对特定属性进行过滤(例如,现在我只能按课程名称进行过滤)

在对 <md-table> 进行了更多尝试后,发现您实际上不需要计算 sortColumnsortOrder。不过,您确实需要使用 .sync 修饰符,如文档中所述。

你必须提供一个settermd-table 将尝试分配给已更改的计算值)。但是,您不需要分配任何内容,因为 sortColumnsortOrder 会相应更改,并且您的 getter 会对这些更改做出反应。

我添加了一个 watch,它会在每次 sortColumn 更改时重置 sortOrder - 除此之外,它非常干净。

working demo.

相关代码:

import { sortBy } from 'lodash-es';

{ 
  data: () => ({
    searchTerm: "",
    searchColumn: "corso",
    sortColumn: "corso",
    sortOrder: "asc",
    items: [...]
  }),
  computed: {
    filteredItems() {
      return this.items.filter(
        item => this.searchColumn
          .split(".")
          .reduce((obj, prop) => obj[prop], item)
          .toLowerCase()
          .indexOf(this.searchTerm.toLowerCase()) > -1
      );
    },
    orderedItems: {
      get: function() {
        return sortBy(this.filteredItems, this.sortColumn);
      },
      set: () => {}
    }
  },
  watch: {
    sortColumn() {
      this.$nextTick(() => (this.sortOrder = "desc"));
    }
  },
}