javascript - 如何使用 vue.js 对表格中的日期进行排序

标签 javascript sorting date html-table vue.js

我的表格基于 Vue.js 网站中的 Grid Component Example

我在对表格内的日期进行排序时遇到问题。我从服务器端获取所有表数据作为 JSON。所以在提供的代码中,我只是模拟了var mockDataFromServerSide中的数据。

这是代码:https://jsfiddle.net/5w1wzhvw/3/

HTML 文件:

<!-- component template -->
<script type="text/x-template" id="grid-template">
  <table>
    <thead>
      <tr>
        <th v-for="key in columns"
          v-on:click="sortBy(key)"
          :class="{active: sortKey == key}">
          {{key | capitalize}}
          <span class="arrow"
            :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="
        entry in data
        | filterBy filterKey
        | orderBy sortKey sortOrders[sortKey]">
        <td v-for="key in columns">
          {{entry[key]}}
        </td>
      </tr>
    </tbody>
  </table>
</script>

<!-- demo root element -->
<div id="demo">
  <form id="search">
    Search <input name="query" v-model="searchQuery">
  </form>
  <demo-grid
    :filter-key="searchQuery">
  </demo-grid>
</div>

Js文件:

var gridColumns = ['name', 'date'];
var mockDataFromServerSide = [
      { name: 'Chuck Norris', date: "01 Dec 2016" },
      { name: 'Bruce Lee', date: "23 Apr 2005" },
      { name: 'Jackie C', date: "30 Jan 2012" },
      { name: 'Jet Li', date: "20 Apr 2006" }
    ];
// register the grid component
Vue.component('demo-grid', {
  template: '#grid-template',
  props: {
        filterKey: String
  },
  data: function () {
    var sortOrders = {}
    gridColumns.forEach(function (key) {
      sortOrders[key] = 1
    })
    return {
      sortKey: '',
      sortOrders: sortOrders,
      columns: gridColumns,
      data: mockDataFromServerSide
    }
  },
  methods: {
    sortBy: function (key) {
      this.sortKey = key
      this.sortOrders[key] = this.sortOrders[key] * -1
    }
  }
})

// bootstrap the demo
var demo = new Vue({
  el: '#demo',
  data: {
    searchQuery: ''
  }
})

我还尝试为日期添加过滤器。排序正确,但显示的日期显示为“Thu Apr 02 2016 00:00:00 GMT+0800(中国标准时间)”。我希望日期显示为 2016 年 4 月 2 日

添加过滤器代码:https://jsfiddle.net/kr1m5de5/1/

HTML 文件(添加过滤器):

<!-- component template -->
<script type="text/x-template" id="grid-template">
  <table>
    <thead>
      <tr>
        <th v-for="key in columns"
          v-on:click="sortBy(key)"
          :class="{active: sortKey == key}">
          {{key | capitalize}}
          <span class="arrow"
            :class="sortOrders[key] > 0 ? 'asc' : 'dsc'">
          </span>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="
        entry in data
        | filterBy filterKey
        | orderBy sortKey sortOrders[sortKey]
        | datesFilter">
        <td v-for="key in columns">
          {{entry[key]}}
        </td>
      </tr>
    </tbody>
  </table>
</script>

<!-- demo root element -->
<div id="demo">
  <form id="search">
    Search <input name="query" v-model="searchQuery">
  </form>
  <demo-grid
    :filter-key="searchQuery">
  </demo-grid>
</div>

JS文件(添加过滤器):

var gridColumns = ['name', 'date'];

var mockDataFromServerSide = [
      { name: 'Chuck Norris', date: "01 Dec 2016" },
      { name: 'Bruce Lee', date: "23 Apr 2005" },
      { name: 'Jackie C', date: "30 Jan 2012" },
      { name: 'Jet Li', date: "20 Apr 2006" }
    ];
// register the grid component
Vue.component('demo-grid', {
  template: '#grid-template',
  props: {
        filterKey: String
  },
  filters: {
    datesFilter: function (data) {
      data.forEach(function (row) {
        row.date = new Date(row.date);
      });
      return data;
        }
    },
  data: function () {
    var sortOrders = {}
    gridColumns.forEach(function (key) {
      sortOrders[key] = 1
    })
    return {
      sortKey: '',
      sortOrders: sortOrders,
      columns: gridColumns,
      data: mockDataFromServerSide
    }
  },
  methods: {
    sortBy: function (key) {
      this.sortKey = key
      this.sortOrders[key] = this.sortOrders[key] * -1
    }
  }
})

// bootstrap the demo
var demo = new Vue({
  el: '#demo',
  data: {
    searchQuery: ''
  }
})

请让我知道如何修复它,或者是否有更好的方法。

最佳答案

我通过制作一个 TableHeader 组件解决了这个问题,它说语义因为我使用了 semantic-ui...抱歉代码中的西类牙式英语,无论如何它们必须是同源词。此外,此代码有效,但如果您发现代码/答案有所改进,请告诉我!

如您所见,我真的没有在前面排序...我用已排序的项目发出新请求。

<template>
    <th @click="cycleSort(sth, $event)">
        <span><span>{{ sth.texto }}&nbsp;&nbsp;</span><i class="icon" :class="sth.icon"></i><sub v-if="sth.posicion > 0"><small>{{ sth.posicion }}</small></sub></span>
    </th>
</template>
<script>
export default {
  name: "SemanticTableHeader",
  props: {
      sth : {
          type : Object,
          default: () => {}
      },
      sths : {
          type : Array,
          default: () => { return [] }
      },
      filtrosOrder : {
          type : Array,
          default: () => { return [] }
      },
      isSearching : {
          type : Boolean,
          required : true
      }
  },
  methods: {
      cycleSort(sth, event) {

          if(this.isSearching == true){
              return false;
          }

          switch (sth.direction) {
              case null:
              sth.direction = 'asc';
              sth.icon = 'sort ascending';
              break;

              case 'asc':
              sth.direction = 'desc';
              sth.icon = 'sort descending';
              break;

              case 'desc':
              sth.direction = null;
              sth.icon = 'sort disabled';
              break;

              default:
              sth.direction = null;
              sth.icon = 'sort disabled';
          }

        this.manejaCambioHeader(sth);

      },
      manejaCambioHeader: _.debounce(function (sth) {
          var self = this;

          console.log(this.filtrosOrder);

          let auxUser = _.find(this.filtrosOrder, function(o) { return o.id == sth.id; });

          if( auxUser != null ){

              auxUser.direction = sth.direction;

              if(auxUser.direction == null){
                  for (var i=0 ; i < this.filtrosOrder.length ; i++){
                      if (this.filtrosOrder[i].id === auxUser.id) {

                          let auxSths =  _.find(self.sths, function(o) { return o.id == sth.id; });
                          auxSths.posicion = 0;

                          this.filtrosOrder.splice(i, 1);
                      }
                  }
              }
          }else{
              this.filtrosOrder.push({ id: sth.id, direction: sth.direction });
          }

          for (var i=0 ; i < self.filtrosOrder.length; i++){
              let auxSths =  _.find(this.sths, function(o) { return o.id == self.filtrosOrder[i].id; });

              auxSths.posicion = i + 1;
          }

          console.log(this.filtrosOrder);

          this.$emit('sortHeaderChanged', sth);

    }, 400),
  },
}
</script>
<style lang="css" scoped>
th span{
    cursor: pointer !important;
    -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
    -khtml-user-select: none; /* Konqueror HTML */
    -moz-user-select: none; /* Firefox */
    -ms-user-select: none; /* Internet Explorer/Edge */
    user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
}

i.icon{
    margin: 0em -0.2em 0em 0em;
}
</style>

在我的索引 View 中,我只是加载组件并像这样使用它

<template>
    <table>
        <thead>
            <tr>
                <semantic-table-header v-for="sth in sths" :key="sth.key"
                :sth="sth"
                :sths="sths"
                :isSearching="isSearching"
                :filtrosOrder="filtros.orderBy"
                @sortHeaderChanged="fetchIndex"
                ></semantic-table-header>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr v-for="contact in contacts" :key="contact.key" :class="[contact.justAdded ? 'justAdded' : '']">
            </tr>
        </tbody>
    </table>
</template>

export default {
    name: "ContactsIndex",
    data:() => ({
        filtros:{
            orderBy:[
                {   id: 'nombre',   direction: 'asc'    } // orderBy is calculated through the headers component
            ]
        },
        sths:[
            {   id: 'nombre',       texto: 'Nombre',                icon: 'sort ascending',     direction: 'asc',   posicion: 1 },
            {   id: 'telefonos',    texto: 'Teléfono(s)',           icon: 'sort disabled',      direction: null,    posicion: 0 },
            {   id: 'emails',       texto: 'Correo Electrónico(s)', icon: 'sort disabled',      direction: null,    posicion: 0 },
            {   id: 'estatus',      texto: 'Estatus',               icon: 'sort disabled',      direction: null,    posicion: 0 }
        ],
        contacts: [],
    }),
    created() {
        this.fetchIndex();
    },
    methods: {
        resetFilters() {
            // this function is to reset filters and headers
            Object.assign(this.$data.filtros, this.$options.data().filtros);
            this.$data.sths =  this.$options.data().sths;
            this.fetchIndex();
        },
        fetchIndex() {
            let self = this;

            // this is a wrapper i made for an axios post call you can replace it with a normal call
            singleIndexRequest('/api/v1/contacts/index', self).then(response => {
                self.contacts = response.data.contacts;
            });
        },
    }
}

关于javascript - 如何使用 vue.js 对表格中的日期进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36369708/

相关文章:

javascript - 在 Vue.js 中调用 axios POST 时真的有必要定义端点吗?

algorithm - 对具有 O(n*Log(K)) 复杂度的近排序数组进行排序

javascript - 为什么 JavaScript 中的 ".sort()"将非常小的数字排序为非常大的数字?

java - 将日期字符串解析为另一种格式

javascript - 在 Javascript 中获取两 (2) 个日期之间 *每年* 的月数 [Ex : Aug 2019 - Aug 2022]

javascript - 如何将 Markdown 解析为 AST,对其进行操作,然后将其写回 Markdown?

javascript - 为什么在 removeItem 中不需要括号?为什么 li.onclick = removeItem 必须在 newItem() 函数内?

javascript - 安全地将 Ruby 对象传递给 JavaScript

php - 按日期字段对对象数组进行排序

javascript - Angular js - 在 $scope 中增加月份