如何在Vue模板中对对象中的数据进行排序?

时间:2017-06-14 17:36:08

标签: vue.js

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

我想保留这些密钥以进行更新。

但是,当我在Vue-templates中渲染数据时,我也希望像数组一样对数据进行排序。

数据如下:

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" } } ]

1 个答案:

答案 0 :(得分:2)

像这样的东西。在这里,我显然没有使用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是一个排序函数 generator 。您传递任何属性名称,它将为具有该属性的对象生成排序函数。为了处理topics中的数据结构,我添加了一个getter参数,您可以使用该参数告诉分拣机 如何获取所需的对象排序。

我最初担心v[Object.keys(v)[0]]的表现,但在comments here中似乎至少可以解决这个问题。

如果您不必支持IE,或者您正在使用可以编译支持它的javascript,那么您也可以在不需要排序的情况下为getter参数定义默认值通过嵌套对象。

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

然后您可以将其用作

const sorter = this.sortByObjectProperty("someProperty")