我一直在项目上使用vue js 1.27,我需要能够按数值,字母和反向顺序对列表进行排序。 我整天都在尝试这一点而没有取得太大进展。
我在代码示例中留下了以前的一些代码,让您知道我已尝试过的内容。
谢谢
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrap">
<h2>Select a category</h2>
<ul id="categorySelect">
<li v-for="cat in categories | orderBy reverse" @click="selectCategory(cat)" class="${cat.selectedCategory == category ? 'selected' : ''}">${cat.title}</li>
</ul>
</div>
{% endblock %}
{% block javascripts %}
<script type="text/javascript">
Vue.config.delimiters = ['${', '}'];
new Vue({
el: '#wrap',
data: {
//reverse: -1,
wasClicked: true,
selectedCategory: null,
categories: [{
title: 'ALL',
category: null
},
{
title: 'CATE',
category: 'sport'
},
{
title: 'DOG',
category: 'sport'
},
{
title: 'SPEED',
category: 'sport'
},
{
title: 'CAT',
category: 'sport'
},
{
title: 'SPORT',
category: 'sport'
},
{
title: 'ART',
category: 'sport'
},
{
title: 'PEOPLE',
category: 'people'
},
{
title: 'CAR',
category: 'car'
}]
},
filters: {
categoryFilter: function (infoBlocs) {
return this.wasClicked ? this.categories : {};
},
caseFilter: function () {
if (this.wasClicked) {
return this.reverseArray();
}
return this.alphaSortByKey(this.categories, 'category');
},
reverse: function(value) {
// slice to make a copy of array, then reverse the copy
return value.slice().reverse();
}
},
methods: {
selectCategory: function(category) {
//this.wasClicked =! this.wasClicked;
//this.categories = this.alphaSortByKey(this.categories, 'category');
// if (this.reverse) {
// this.categories = this.alphaSortByKey(this.categories, 'category');
// }
// else {
// this.categories = this.reverseArray();
// }
if (this.reverse) {
this.categories = this.alphaSortByKey(this.categories, 'category');
this.reverse = false;
}
else {
this.categories = this.reverseArray();
//this.reverse = true;
}
},
alphaSortByKey: function (arr, key) {
arr.sort(function (a, b) {
if (a[key] < b[key])
return -1;
if (a[key] > b[key])
return 1;
return 0;
});
return arr;
},
reverseArray: function () {
return this.categories.reverse();
},
changeOrder: function (event) {
var self = this;
self.reverse = self.reverse * -1
var newItems = self.categories.slice().sort(function (a, b) {
var result;
if (a.name < b.name) {
result = 1
}
else if (a.name > b.name) {
result = -1
}
else {
result = 0
}
return result * self.reverse
})
newItems.forEach(function (item, index) {
item.position = index;
});
this.categories = newItems;
}
}
});
</script>
{% endblock %}
答案 0 :(得分:3)
这是一个工作功能的小提琴,用于排序和反转数组的顺序。对于反向我只使用内置的reverse()Javascript函数。对于字母数字排序,我借用了这个答案的解决方案:https://stackoverflow.com/a/4340339/6913895
https://jsfiddle.net/n1tbmgo9/
HTML:
<div id="wrap">
<h2>Select a category</h2>
<button @click="sort">
Sort alphanumeric
</button>
<button @click="reverse">
Reverse list
</button>
<ul id="categorySelect">
<li v-for="cat in categories">${cat.title}</li>
</ul>
</div>
使用Javascript:
Vue.config.delimiters = ['${', '}'];
new Vue({
el: '#wrap',
data: {
selectedCategory: null,
categories: [{
title: 'ALL',
category: null
},
{
title: 'CATE',
category: 'sport'
},
{
title: 'DOG',
category: 'sport'
},
{
title: 'SPEED',
category: 'sport'
},
{
title: 'CAT',
category: 'sport'
},
{
title: 'SPORT',
category: 'sport'
},
{
title: 'ART',
category: 'sport'
},
{
title: 'PEOPLE',
category: 'people'
},
{
title: 'CAR',
category: 'car'
}]
},
methods: {
sort: function () {
this.categories.sort(this.sortAlphaNum);
},
reverse: function () {
this.categories.reverse();
},
sortAlphaNum: function (a,b) {
var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;
var aA = a.title.replace(reA, "");
var bA = b.title.replace(reA, "");
if(aA === bA) {
var aN = parseInt(a.title.replace(reN, ""), 10);
var bN = parseInt(b.title.replace(reN, ""), 10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
return aA > bA ? 1 : -1;
}
}
}
});
内置的reverse()
函数非常简单,因此我将详细介绍sortAlphaNum()
排序函数。该函数被传递到sort()
函数,并且必须返回1,0或-1,以指示传入的对象是否应该在数组中的特定方向上移动。
变量reA
和reN
是正则表达式,分别用于标识字母和数字字符。
首先,该函数从传入的两个对象的标题中删除所有字母字符,并将它们进行相等性比较
var aA = a.title.replace(reA, "");
和
var bA = b.title.replace(reA, "");
如果它们不相等则意味着我们有字母字符(而不仅仅是数字输入),我们可以相应地对它们进行排序。
return aA > bA ? 1 : -1;
如果剥离字母字符的标题相等(if(aA === bA)
),则我们从对象标题中删除数字(保留非数字字符)。
var aN = parseInt(a.title.replace(reN, ""), 10);
var bN = parseInt(b.title.replace(reN, ""), 10);
然后我们比较结果变量并返回适当的排序值(1,0,-1)。
return aN === bN ? 0 : aN > bN ? 1 : -1;
答案 1 :(得分:0)
创建一个计算属性,您可以手动对其进行排序,然后为其循环而不是数据prop
答案 2 :(得分:0)
有我的 List Component 实现和客户端订单实现:
<template>
<div>
<table class="table table-bordered" v-if="data.length">
<thead>
<tr>
<th v-for="(colValue, colKey) in cols" :key="colKey">
<a @click="sort(colKey)" href="javascript:void(0)">
{{colValue}}
<icon :name="(sortColumn === colKey) ? (sortAsc ? 'sort-down' : 'sort-up') : 'sort'"></icon>
</a>
</th>
</tr>
</thead>
<tbody>
<tr v-for="row in data" :key="row.id">
<td v-for="(colValue, colKey) in cols" :key="row.id + colKey">{{row[colKey]}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import _ from 'lodash';
import apiServer from '@/utils/apiServer'; //
export default {
name: 'List',
data() {
return {
data: [],
sortColumn: '',
sortAsc: true
};
},
props: {
cols: {
type: Object,
required: true
},
apiEndpoint: {
type: String,
required: true
}
}
created() {
this.fetchData();
},
watch: {
'$route': 'fetchData'
},
methods: {
async fetchData() {
const response = await apiServer.get(this.apiEndpoint);
this.data = response.data;
},
sort(colKey) {
this.data = _.sortBy(this.data, [colKey]);
if (this.sortColumn === colKey) {
if (!this.sortAsc) {
this.data = _.reverse(this.data);
}
this.sortAsc = !this.sortAsc;
} else {
this.sortAsc = false;
}
this.sortColumn = colKey;
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
<template>
<div>
<h1>Orders</h1>
<List :cols="cols" api-endpoint="/orders" title="Orders" />
</div>
</template>
<script>
import List from '@/components/List.vue';
export default {
name: 'OrderList',
components: { List },
data() {
return {
cols: {
id: 'Id',
title: 'Title',
created_at: 'Created at'
}
};
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>