Vue.js orderBy 无法正确处理大写和小写

Vue.js orderBy does not work properly with uppercase and lowercase

我正在使用 Laravel 5.2 + Vuejs + Vueify 开发一个应用程序,我在 table 上列出了一个对象数组,但我有 2 个问题。

1. orderBy 工作在大小写分隔

orderBy应用首字母大小写分隔记录!

2。过滤器字段中的特价字符

在筛选字段中键入“Água”找不到 "Agua" 结果,因为字母 A 上的重音符号很重,我想忽略口音...这可能吗?

JS 文件

Vue.filter('pmlOrderBy', function(arr, sortKey, reverse) {

  if (!sortKey) {
    return arr;
  }
  var order = (reverse && reverse < 0) ? -1 : 1;

  // sort on a copy to avoid mutating original array
  return arr.slice().sort(function(a, b) {
    if (sortKey !== '$key') {
      if (Vue.util.isObject(a) && '$value' in a) a = a.$value;
      if (Vue.util.isObject(b) && '$value' in b) b = b.$value;
    }
    a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a;
    b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b;

    a = a.toLowerCase();
    b = b.toLowerCase();

    //         return a.localeCompare(b) * order;

    return a === b ? 0 : a > b ? order : -order;
  });
});


new Vue({

  el: 'body',

  data: {
    record: {},
    selected: [],
    list: [{
      name: 'Google',
      id: 1,
    }, {
      name: 'Água',
      id: 2,
    }, {
      name: 'Agua Branca',
      id: 3,
    }, {
      name: 'first time',
      id: 4,
    }, {
      name: 'boston',
      id: 5,
    }, {
      name: 'Type',
      id: 6,
    }, {
      name: 'Facebook',
      id: 7,
    }, ],
    sortProperty: 'name',
    sortDirection: 1,
  },

  methods: {

    sort: function(property) {
      this.sortProperty = property;
      this.sortDirection = (this.sortDirection == 1) ? -1 : 1;
    },

  }

});

HTML 文件

<div class="container">
  <input type="text" v-model="textFilter" class="form-control" placeholder="Type to filter...">
</div>

<hr>

<div class="container">
  <div class="alert alert-info">Click at the TH to sort</div>
  <table class="table table-striped table-bordered">
    <thead>
      <tr>
        <th @click="sort('id')" style="cursor: pointer;">Id</th>
        <th @click="sort('name')" style="cursor: pointer;">Name</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="r in list | filterBy textFilter | pmlOrderBy sortProperty sortDirection">
        <td class="text-center" style="width:90px">{{ r.id }}</td>
        <td>{{ r.name }}</td>
      </tr>
    </tbody>
  </table>
</div>

JS Bin

==== 已编辑 ====

随着 Taylor 和 RainningChain 的帮助,我们几乎到了那里!

我找到this article并更新了上面的代码和JS Bin,但现在的问题是:

有人吗?

谢谢!

为此,您必须创建自己的过滤器。

扩展 Vue 的 orderBy 过滤器,这将是解决您的两个问题的实用方法。

// This was originally copied from the Vue source
// File: src/filters/array-filters.js
function orderByWords (arr, sortKey, reverse) {
  arr = convertArray(arr)
  if (!sortKey) {
    return arr
  }
  var order = (reverse && reverse < 0) ? -1 : 1
  // sort on a copy to avoid mutating original array
  return arr.slice().sort(function (a, b) {
    if (sortKey !== '$key') {
      if (isObject(a) && '$value' in a) a = a.$value
      if (isObject(b) && '$value' in b) b = b.$value
    }
    a = isObject(a) ? getPath(a, sortKey) : a
    b = isObject(b) ? getPath(b, sortKey) : b
    return a.localeCompare(b) * order
  })
}

过滤器的核心是这里的这个片段: a.localeCompare(b)

String.prototype.localeCompare 方法根据初始字符串 (a) 是在比较字符串 (b 之前还是之后来比较两个字符串和 returns 一个整数值).

更新

事实证明过滤器坏了,因为 Number.prototype.localeCompare 不存在...谁知道?

所以我们可以使用一点类型转换技巧来让它在任何地方工作。

Vue.filter('pmlOrderBy', function (arr, sortKey, reverse) {
    if (!sortKey) {
        return arr;
    }
    var order = (reverse && reverse < 0) ? -1 : 1;

    // sort on a copy to avoid mutating original array
    return arr.slice().sort(function (a, b) {
        if (sortKey !== '$key') {
            if (Vue.util.isObject(a) && '$value' in a) a = a.$value;
            if (Vue.util.isObject(b) && '$value' in b) b = b.$value;
        }
        a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a;
        b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b;

        return (''+a).localeCompare((''+b)) * order;
    });
});

关键行是过滤器的最后一行。 (''+a).localeComparea 强制转换为 String,然后调用 localeCompare 方法。