【问题标题】:How To Sort Data From An Object In Vue templates?如何在 Vue 模板中对对象中的数据进行排序?
【发布时间】:2017-06-14 17:36:08
【问题描述】:

我正在使用 Firebase。数据存储为具有唯一键的对象。

我想保留这些密钥用于更新。

但是,在我的 Vue 模板中呈现数据时,我还想像数组一样对数据进行排序。

数据如下:

topics:
  - [firebase-push-key]
    - title
    - text
    - ...

我想在我的模板中对其进行排序,例如:

<template v-for="topic in $store.state.forum.topics">
  ...
</template>

$store.state.forum.topics 应按值title 排序。

编辑:

这个 Vuex 突变可以完成这项工作:

retrieveTopics(state) {
  topics.on('value', (snapshot) => {
    const object = snapshot.val()
    var array = Object.keys(object).map((key) => {
      return { [key]: object[key] }
    })
    state.forum.topics = array
  })
}

但是如何在 vue 模板中迭代生成的数组呢?

这是数据结构:

[ { "-Kmbspn0WYBlNXfmfVlR": { "slug": "arne", "title": "Arne" } }, { "-KmbsqiG_9uXzRhHrnXZ": { "slug": "tati", "title": "Tati" } }, { "-KmbsrllgJzV7BA_NeCO": { "slug": "abel", "title": "Abel" } } ]

【问题讨论】:

  • 使用计算值。
  • 你能举个例子吗?
  • 您能否举例说明您的数据以及您希望如何对其进行排序?
  • 舒尔。等一下。

标签: vue.js


【解决方案1】:

类似的东西。这里我显然没有使用 Vuex,但你可以使用 Vuex getter。如果您需要排序对象中主题的id,您可以将其添加到您的地图中。

console.clear()

// topics:
//   - [firebase-push-key]
//     - title
//     - text
//     - ...
  
const topics = {
  "1234":{
    title: "Ziss one starts with Z",
    text: "text1"
  },
  "2345":{
    title: "M is for middle",
    text: "text2"
  },
  "3456":{
    title: "Alpha title",
    text: "text3"
  }
}

new Vue({
  el:"#app",
  data:{
    topics
  },
  methods:{
    sortProperty(prop){
      return (a,b) => {
        if (a[prop] < b[prop])
          return -1;
        if (a[prop] > b[prop])
          return 1;
        return 0;       
      }
    }
  },
  computed:{
    sortedTopics(){
      return Object.keys(this.topics)
        .map(t => {
          this.$set(this.topics[t], 'key', t)
          return this.topics[t]
        })
        .sort(this.sortProperty('title'))
    }
  }
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <div v-for="topic in sortedTopics">
    {{topic}}
  </div>
</div>

编辑

这是一个处理更新数据结构的示例。

const topics = [{
  "-Kmbspn0WYBlNXfmfVlR": {
    "slug": "arne",
    "title": "Arne"
  }
}, {
  "-KmbsqiG_9uXzRhHrnXZ": {
    "slug": "tati",
    "title": "Tati"
  }
}, {
  "-KmbsrllgJzV7BA_NeCO": {
    "slug": "abel",
    "title": "Abel"
  }
}]

new Vue({
  el: "#app",
  data: {
    topics
  },
  methods: {
    sortByObjectProperty(prop, getter) {
      return (a, b) => {
        a = getter(a), b = getter(b)
        if (a[prop] < b[prop])
          return -1;
        if (a[prop] > b[prop])
          return 1;
        return 0;
      }
    }
  },
  computed: {
    sortedTopics() {
      const getter = v => v[Object.keys(v)[0]]
      const sorter = this.sortByObjectProperty("title", getter)
      return this.topics.sort(sorter)
    }
  }
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
  <div v-for="topic in sortedTopics">
    {{topic}}
  </div>
</div>

在这段代码中(和上面的代码一样),sortByObjectProperty 是一个排序函数生成器。您将任何属性名称传递给它,它将为具有该属性的对象生成排序函数。为了处理您在topics 中的数据结构,我添加了一个getter 参数,您可以使用该函数告诉排序器如何 获取它需要排序的对象。

我最初担心v[Object.keys(v)[0]] 的性能,但这似乎在comments here 中得到了解决,至少我自己很满意。

如果您不必支持 IE,或者您正在使用可以编译为支持它的 javascript 的东西,您还可以为 getter 参数定义一个默认值,以防您不需要按嵌套对象。

sortByObjectProperty(prop, getter = g => g) {...}

然后你可以用作

const sorter = this.sortByObjectProperty("someProperty")

【讨论】:

  • 谢谢,但如果我想更新数据,如何保留 Firebase-Push-Key??
  • @TimoMüller 我在帖子中提到了你的可能,但我更新了代码以显示它。
  • 如果你能把它评论出来会很有帮助!谢谢
  • @TimoMüller 对不起,我不明白。我更新了代码以实际添加密钥。
  • 难道没有更好的解决方案,一个是一行,而不是那么多样板代码?!?!
猜你喜欢
  • 2012-08-27
  • 1970-01-01
  • 2020-11-28
  • 2019-03-28
  • 2016-09-05
  • 1970-01-01
  • 2017-10-21
  • 1970-01-01
  • 2014-02-26
相关资源
最近更新 更多