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>
==== 已编辑 ====
随着 Taylor 和 RainningChain 的帮助,我们几乎到了那里!
我找到this article并更新了上面的代码和JS Bin,但现在的问题是:
- 排序正确,但如果我尝试对其他列进行排序,请单击另一个 TH,它会停止。
- 特殊字符的问题依然存在=/
有人吗?
谢谢!
为此,您必须创建自己的过滤器。
扩展 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).localeCompare
将 a
强制转换为 String
,然后调用 localeCompare
方法。
我正在使用 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>
==== 已编辑 ====
随着 Taylor 和 RainningChain 的帮助,我们几乎到了那里!
我找到this article并更新了上面的代码和JS Bin,但现在的问题是:
- 排序正确,但如果我尝试对其他列进行排序,请单击另一个 TH,它会停止。
- 特殊字符的问题依然存在=/
有人吗?
谢谢!
为此,您必须创建自己的过滤器。
扩展 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).localeCompare
将 a
强制转换为 String
,然后调用 localeCompare
方法。