Vuetify DataTable监视未触发

时间:2019-05-08 08:40:18

标签: vue.js datatable vuejs2 vuetify.js vue-data-tables

单击标题项时执行的“更改排序”功能不会触发监视,该监视将从服务器获取更新的数据。另一方面,如果我尝试在changeSort方法的末尾执行fetchRecords方法,则会多次触发手表

我需要在服务器端分页和排序中使用Vuetify数据表,并在标头和项目中使用模板。我实现了类似于Vuetify示例的代码:文档https://vuetifyjs.com/en/components/data-tables#api中的“对服务器端进行分页和排序”和“插槽:项目和标题”。

<template>
  <v-card class="table-container">
    <v-card-title>
      <v-text-field
        v-model="searchField"
        @blur="fetchRecords()"
        @keyup.enter="fetchRecords()"
      />
    </v-card-title>
    <v-data-table
      :headers="headers"
      :items="applications.applications"
      :loading="paginationLoading"
      :pagination.sync="pagination"
      :total-items="pagination.totalItems"
      no-data-text="No results"
    >
      <template v-slot:headers="props">
        <tr>
          <th colspan="4">Dane kandydata</th>
          <th colspan="4">Dane polecającego</th>
          <th colspan="2">Inne</th>
        </tr>
        <tr>
          <th
            v-for="header in props.headers"
            :key="header.value"
            :class="['column', 
              header.sortable !== false ? 'sortable' : '' ,
              pagination.descending ? 'desc' : 'asc', 
              header.value === pagination.sortBy ? 'active' : '']"
            @click="changeSort(header.value, header.sortable)"
          >
            {{ header.text }}
            <v-icon v-if="header.sortable !== false" small>fas fa-sort-up</v-icon>
          </th>
        </tr>
      </template>
      <template v-slot:items="props">
        <td>{{ props.item.candidateName }}</td>
        <td>{{ props.item.candidateSurname }}</td>
        <td>{{ props.item.candidateEmail }}</td>
        <td>{{ props.item.candidatePhone }}</td>
        <td>{{ props.item.referrerName }}</td>
        <td>{{ props.item.referrerSurname }}</td>
        <td>{{ props.item.referrerEmail }}</td>
        <td>{{ props.item.referrerPhone }}</td>
        <td class="text-md-center">
          <div>
            <v-icon>check_circle_outline</v-icon>
          </div>
        </td>
        <td class="text-md-center">
          <div>
            <v-icon>check_circle_outline</v-icon>
          </div>
        </td>
      </template>
      <v-alert v-slot:no-results :value="true" color="error" icon="warning">
        Your search for "{{ searchField }}" found no results.
      </v-alert>
    </v-data-table>
  </v-card>
</template>

<script>
  import { mapState, mapActions } from 'vuex';

  export default {
    data () {
      return {
        announcementId: '',
        announcementTitle: '',
        searchField: '',
        headers: [
          { text: 'Imię', value: 'candidateName' },
          { text: 'Nazwisko', value: 'candidateSurname' },
          { text: 'Email', value: 'candidateEmail', sortable: false },
          { text: 'Telefon', value: 'candidatePhone' },
          { text: 'Imię', value: 'referrerName' },
          { text: 'Nazwisko', value: 'referrerSurname' },
          { text: 'Email', value: 'referrerEmail', sortable: false },
          { text: 'Telefon', value: 'referrerPhone' },
          { text: 'Status', value: 'processed' },
          { text: 'Akcje', value: 'actions', sortable: false },
        ],
        pagination: {
          page: 1,
          rowsPerPage: 10,
          totalItems: 10,
          sortBy: '',
          descending: false,
        },
        paginationLoading: false
      }
    },
    computed: {
      ...mapState([
        'applications',
      ])
    },
    watch: {
      pagination: {
        handler(newVal, oldVal){
          if(newVal != oldVal){
            this.fetchRecords()
          }
        },
        deep: true
      }
    },
    methods: {
      ...mapActions([
        'getApplications',
      ]),
      fetchRecords () {
        this.paginationLoading = true
        this.getApplications({
          announcementId: this.announcementId,
          pagination: this.pagination,
          search: this.searchField
        })
        .then(
          response => {
            this.paginationLoading = false
            if(this.pagination.totalItems != response.totalItems) this.pagination.totalItems = response.totalItems
          }
        )
        .catch(
          err => {
            console.log(err);
          }
        )
    },
    changeSort (columnValue, sortable) {
      if(sortable === false){
        return
      }
      if (this.pagination.sortBy === columnValue) {
        this.pagination.descending = !this.pagination.descending
        console.log(this.pagination.descending);
      } else {
        this.pagination.sortBy = columnValue
        this.pagination.descending = false
      }
    },
    editTableItem(item){
      console.log(item);
    },
    onClearSearch() {
      this.searchField = ''
      this.fetchRecords()
    },
  }
}
</script>

1 个答案:

答案 0 :(得分:0)

更改pagination对象时应创建新对象。在这里,我使用ES6语法:

changeSort (columnValue, sortable) {
    if(sortable === false){
      return
    }
    if (this.pagination.sortBy === columnValue) {
      this.pagination = {
        ...this.pagination,
        descending: !this.pagination.descending
      }
      console.log(this.pagination.descending);
    } else {
      this.pagination = {
        ...this.pagination,
        sortBy: columnValue,
        descending: false
      }
    }
}