【问题标题】:Vue.js orderBy does not work properly with uppercase and lowercaseVue.js orderBy 不能正常使用大写和小写
【发布时间】:2016-04-02 00:49:06
【问题描述】:

我正在使用 Laravel 5.2 + Vuejs + Vueify 开发一个应用程序,我在表格中列出了一个对象数组,但我有 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,但现在的问题是:

  • 排序正确,但如果我尝试对其他列进行排序,单击另一个 TH 会刹车。
  • 特殊字符的问题仍然存在 =/

有人吗?

谢谢!

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    为了实现这一点,您必须创建自己的过滤器。

    扩展 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
      })
    }
    

    过滤器的核心是这里的 sn-p: a.localeCompare(b)

    String.prototype.localeCompare 方法比较两个字符串,并根据初始字符串 (a) 是在比较字符串 (b) 之前还是之后返回一个整数值。

    更新

    原来过滤器坏了,因为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).localeCompare 会将 a 强制转换为 String,然后调用 localeCompare 方法。

    【讨论】:

    • 值得一提的自定义过滤器可以通过Vue.filter(name,customOrderByFunc)创建。
    • 伙计们,我还有问题!我更新了问题!你有什么主意吗? @rainningchain
    • @GustavoBissolli 我已经更新了我的回复,为您添加了更新的过滤器。
    • 干得好@TaylorGlaeser!任何想法如何解决过滤器问题?在 JS Bin 上输入“Agua”并找到“Água”结果会很棒!你知道有什么诀窍吗?我已经将您的答案标记为正确,因为我最大的问题已解决 =) 感谢您!
    • @GustavoBissolli 我可能不得不建议将这项工作卸载到 NPM 模块。像github.com/andrewrk/node-diacritics 这样的东西会是一个不错的选择。您必须通过将规范化字符串与您的搜索进行比较的过滤器来运行每个选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    相关资源
    最近更新 更多