Javascript 如何在 Vue JS 中使用 v-for 和 orderBy 过滤器反转数组的顺序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37638083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:32:47  来源:igfitidea点击:

How do I reverse the order of an array using v-for and orderBy filter in Vue JS?

javascriptarraysvue.js

提问by Soviut

I am using Vue JS to do viewmodel bindings. In my dataobject I have an array of items that are sorted in ascending order (oldest to newest) and I'd like to keep it that way for code-based reasons.

我正在使用 Vue JS 进行视图模型绑定。在我的data对象中,我有一个按升序(从最旧到最新)排序的项目数组,出于基于代码的原因,我想保持这种方式。

var v = new Vue({
    el: '#app',
    data: {
        items: [
            {id: 51,  message: 'first'},
            {id: 265, message: 'second'},
            {id: 32,  message: 'third'}
        ],
    }
}

However, when I display the array in the template I'd like to reverse the order so that it's descending (newest to oldest). I tried the following:

但是,当我在模板中显示数组时,我想颠倒顺序,使其降序(从最新到最旧)。我尝试了以下方法:

<ol>
    <li v-for="item in items | orderBy -1" track-by="id">

This didn't work since the orderByfilter seems to require a field name as its first argument.

这不起作用,因为orderBy过滤器似乎需要一个字段名称作为它的第一个参数。

Is there any way to accomplish this in the template using the v-forsyntax using the orderByfilter? Or am I going to have to create a custom reversefilter?

有什么方法可以使用v-for使用orderBy过滤器的语法在模板中完成此操作吗?还是我必须创建自定义reverse过滤器?

采纳答案by Pantelis Peslis

Note:The below works in Vue 1, but in Vue 2 filters are deprecated and you will see: ' Property or method "reverse" is not defined on the instance but referenced during render.' See tdom_93'sanswer for vue2.

注意:以下内容在 Vue 1 中有效,但在 Vue 2 中不推荐使用过滤器,您将看到:“属性或方法“reverse”未在实例上定义,但在渲染期间被引用。参见tdom_93对 vue2回答。

You could create a custom filter to return the items in reversed order:

您可以创建一个自定义过滤器来以相反的顺序返回项目:

Vue.filter('reverse', function(value) {
  // slice to make a copy of array, then reverse the copy
  return value.slice().reverse();
});

Then use it in the v-forexpression:

然后在v-for表达式中使用它:

<ol>
    <li v-for="item in items | reverse" track-by="id">

https://jsfiddle.net/pespantelis/sgsdm6qc/

https://jsfiddle.net/pespantelis/sgsdm6qc/

回答by NimaAJ

Simple and concise solution:

简单明了的解决方案:

<li v-for="item in items.slice().reverse()">
//do something with item ...
</li>

回答by t_dom93

Update for Vue2

更新 Vue2

I want to show some ways that you can work with data and not using filters as they are deprecatedin Vue2:

我想展示一些可以处理数据而不是使用过滤器的方法,因为它们在 Vue2中弃用

inside computed property

内部计算属性

Use computed properties in place of filters, which is much better because you can use that data everywhere in component, not only just in template: jsFiddle

使用计算属性代替过滤器,这要好得多,因为您可以在组件中的任何地方使用该数据,而不仅仅是在模板中: jsFiddle

computed: {
    reverseItems() {
        return this.items.slice().reverse();
  }     
}

inside Vuex getter property

在 Vuex getter 属性中

If you're using Vuex, and you store your data in store.stateobject. The best way do some transformation with data stored in state is to do that in gettersobject (for example filtering through a list of items and counting them, reverse order and so on...)

如果您使用 Vuex,并且您将数据存储在store.stateobject. 对存储在状态中的数据进行一些转换的最佳方法是在getters对象中进行转换(例如过滤项目列表并对其进行计数、倒序等等...

getters: {
    reverseItems: state => {
        return state.items.slice().reverse();
    }
}

and retrieve state from getters in component computed property:

并从组件计算属性中的 getter 中检索状态:

computed: {
    showDialogCancelMatch() {
        return this.$store.state.reverseItems;
    }
}

回答by kirschkern

Instead of reversing the order of the elements for creation, I only change the order of the display.

我只是改变了显示的顺序,而不是颠倒创建元素的顺序。

<ol class="reverseorder">
    <li v-for="item in items" track-by="id">

And my CSS

还有我的 CSS

<style>
.reverseorder {
  display: flex;
  flex-direction: column-reverse;
}
</style>

No need to clone the array and reverse it.

无需克隆数组并反转它。

回答by John Carrell

For my use case (which is admittedly, apparently different than the OP...) I wanted to have the indices of the Array in reverse orderin the v-for "loop."

对于我的用例(诚然,显然与 OP 不同......)我希望在 v-for“循环”中以相反的顺序排列数组的索引。

My solution was to create a Vue app method reverseRange(length)that returns an Array of integers from length-1 to 0. I then used that in my v-fordirective and simply referred to my Array elements as myArray[index]every time I needed it.

我的解决方案是创建一个 Vue 应用程序方法reverseRange(length),该方法返回一个长度为 1 到 0 的整数数组。然后我在我的v-for指令中使用它,并在myArray[index]每次需要时简单地引用我的 Array 元素。

That way, the indices were in reverse order and I was able to then use them to access elements of the Array.

这样,索引的顺序是相反的,然后我就可以使用它们来访问数组的元素。

I hope this helps someone who landed on this page with this subtle nuance in their requirements like me.

我希望这可以帮助那些像我一样在他们的需求中有这种细微差别的人登陆这个页面。

回答by ErikOlson186

The v-for directive doesn't support iterating backwards, so if you want to order by newest you're going to need to add another field to indicate when the item was added, or change idto increment every time an item is added.

v-for 指令不支持向后迭代,因此如果您想按最新排序,则需要添加另一个字段来指示添加项目的时间,或者更改id为每次添加项目时递增。

Then, with fieldbeing the field indicting the order added:

然后,field作为指示订单的字段添加:

<li v-for="item in items | orderBy 'field' -1" track-by="id">