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

SFX*_*SFX 5 javascript sorting html-table date vue.js

我的表基于Vue.js网站上的网格组件示例

我在表中排序日期时遇到问题.我从服务器端获取所有表数据作为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>
Run Code Online (Sandbox Code Playgroud)

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: ''
  }
})
Run Code Online (Sandbox Code Playgroud)

我还尝试在日期中添加过滤器.排序正确但显示的日期显示为" 2016年4月2日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>
Run Code Online (Sandbox Code Playgroud)

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: ''
  }
})
Run Code Online (Sandbox Code Playgroud)

请让我知道如何解决它或是否有更好的方法来解决它.

Eru*_*iel 0

我通过制作一个TableHeader组件解决了这个问题,它说语义原因,因为我使用了语义-ui...对代码中的西班牙英语感到抱歉,无论如何,它们必须是同源的。另外,此代码正在运行,但如果您看到代码/答案的改进,请告诉我!

\n\n

正如您所看到的,我确实没有在前面进行排序...我对排序后的项目提出了一个新请求。

\n\n
<template>\n    <th @click="cycleSort(sth, $event)">\n        <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>\n    </th>\n</template>\n<script>\nexport default {\n  name: "SemanticTableHeader",\n  props: {\n      sth : {\n          type : Object,\n          default: () => {}\n      },\n      sths : {\n          type : Array,\n          default: () => { return [] }\n      },\n      filtrosOrder : {\n          type : Array,\n          default: () => { return [] }\n      },\n      isSearching : {\n          type : Boolean,\n          required : true\n      }\n  },\n  methods: {\n      cycleSort(sth, event) {\n\n          if(this.isSearching == true){\n              return false;\n          }\n\n          switch (sth.direction) {\n              case null:\n              sth.direction = \'asc\';\n              sth.icon = \'sort ascending\';\n              break;\n\n              case \'asc\':\n              sth.direction = \'desc\';\n              sth.icon = \'sort descending\';\n              break;\n\n              case \'desc\':\n              sth.direction = null;\n              sth.icon = \'sort disabled\';\n              break;\n\n              default:\n              sth.direction = null;\n              sth.icon = \'sort disabled\';\n          }\n\n        this.manejaCambioHeader(sth);\n\n      },\n      manejaCambioHeader: _.debounce(function (sth) {\n          var self = this;\n\n          console.log(this.filtrosOrder);\n\n          let auxUser = _.find(this.filtrosOrder, function(o) { return o.id == sth.id; });\n\n          if( auxUser != null ){\n\n              auxUser.direction = sth.direction;\n\n              if(auxUser.direction == null){\n                  for (var i=0 ; i < this.filtrosOrder.length ; i++){\n                      if (this.filtrosOrder[i].id === auxUser.id) {\n\n                          let auxSths =  _.find(self.sths, function(o) { return o.id == sth.id; });\n                          auxSths.posicion = 0;\n\n                          this.filtrosOrder.splice(i, 1);\n                      }\n                  }\n              }\n          }else{\n              this.filtrosOrder.push({ id: sth.id, direction: sth.direction });\n          }\n\n          for (var i=0 ; i < self.filtrosOrder.length; i++){\n              let auxSths =  _.find(this.sths, function(o) { return o.id == self.filtrosOrder[i].id; });\n\n              auxSths.posicion = i + 1;\n          }\n\n          console.log(this.filtrosOrder);\n\n          this.$emit(\'sortHeaderChanged\', sth);\n\n    }, 400),\n  },\n}\n</script>\n<style lang="css" scoped>\nth span{\n    cursor: pointer !important;\n    -webkit-touch-callout: none; /* iOS Safari */\n    -webkit-user-select: none; /* Safari */\n    -khtml-user-select: none; /* Konqueror HTML */\n    -moz-user-select: none; /* Firefox */\n    -ms-user-select: none; /* Internet Explorer/Edge */\n    user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */\n}\n\ni.icon{\n    margin: 0em -0.2em 0em 0em;\n}\n</style>\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
<template>\n    <table>\n        <thead>\n            <tr>\n                <semantic-table-header v-for="sth in sths" :key="sth.key"\n                :sth="sth"\n                :sths="sths"\n                :isSearching="isSearching"\n                :filtrosOrder="filtros.orderBy"\n                @sortHeaderChanged="fetchIndex"\n                ></semantic-table-header>\n                <th></th>\n            </tr>\n        </thead>\n        <tbody>\n            <tr v-for="contact in contacts" :key="contact.key" :class="[contact.justAdded ? \'justAdded\' : \'\']">\n            </tr>\n        </tbody>\n    </table>\n</template>\n\nexport default {\n    name: "ContactsIndex",\n    data:() => ({\n        filtros:{\n            orderBy:[\n                {   id: \'nombre\',   direction: \'asc\'    } // orderBy is calculated through the headers component\n            ]\n        },\n        sths:[\n            {   id: \'nombre\',       texto: \'Nombre\',                icon: \'sort ascending\',     direction: \'asc\',   posicion: 1 },\n            {   id: \'telefonos\',    texto: \'Tel\xc3\xa9fono(s)\',           icon: \'sort disabled\',      direction: null,    posicion: 0 },\n            {   id: \'emails\',       texto: \'Correo Electr\xc3\xb3nico(s)\', icon: \'sort disabled\',      direction: null,    posicion: 0 },\n            {   id: \'estatus\',      texto: \'Estatus\',               icon: \'sort disabled\',      direction: null,    posicion: 0 }\n        ],\n        contacts: [],\n    }),\n    created() {\n        this.fetchIndex();\n    },\n    methods: {\n        resetFilters() {\n            // this function is to reset filters and headers\n            Object.assign(this.$data.filtros, this.$options.data().filtros);\n            this.$data.sths =  this.$options.data().sths;\n            this.fetchIndex();\n        },\n        fetchIndex() {\n            let self = this;\n\n            // this is a wrapper i made for an axios post call you can replace it with a normal call\n            singleIndexRequest(\'/api/v1/contacts/index\', self).then(response => {\n                self.contacts = response.data.contacts;\n            });\n        },\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n