如何按值对计算出的属性进行排序?

问题描述 投票:0回答:1

在看了 Vue.JS的文档我们得到了一个方法,作为一个例子,它可以按照所有的偶数进行排序。这一切都很好,但我想通过数组中的名称值对数组进行排序--这意味着我需要进行比较。我找到的所有答案都已经被废弃了,唯一的解决方案就是使用VueJS本身以外的其他模块。这真的是不可能的,还是我只是错过了一些明显的东西?这是我的例子。

data() {
    return {
        namesArray: []
        ]
    };
  },
...
computed: {
    addToNamesArray(){
        this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
        this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
        this.namesArray.push({"firstName": 'Bertrand', "lastName: ''"})
        return this.namesArray
        //(Obviously more complicated in reality, but let's keep it simple)
    }
}

在Vue中:

<ul>
    <li v-for="(namesList, index) in addNamesToArray" :key="index">
        {{namesList.firstName}}
    </li>
</ul>

试图在计算属性中排序会返回一个 "Unexpected side effect in computed property "的错误,因为在计算属性中不能突变。所以我的第二次尝试是创建一个方法。

methods: {
    sortNames(){
        this.namesArray.sort((a,b) => a.firstName- b.firstName)
    }
}

导致新的计算属性

computed: {
    addToNamesArray(){
        this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
        this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
        this.namesArray.push({"firstName": 'Bertrand', "lastName: ''"})
        this.sortNames()
        return this.namesArray
    }
}

但这什么也做不了(??)

如果有人能给我解释一下为什么这些解决方法不起作用,并给我提供一个<3,我会非常感激。

json vue.js
1个回答
1
投票

好吧,让我们从头开始。

我认为你应该先把addToNamesArray()从... 计算的方法. 所以你可以确定它只被调用一次,当你的数据发生变化时,computed会被更频繁地调用。

你的函数 sortNames 应该被移到 computed 字段,像这样。

mounted(){
    this.addToNamesArray()
},
computed: {
     sortedNames(){
          return this.namesArray.concat().sort((a,b) => a.firstName.localeCompare(b.firstName))
     }
},
methods: {
     addToNamesArray(){
        this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
        this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
        this.namesArray.push({"firstName": 'Bertrand', "lastName": ''})
     }
}

把它放在computed属性里而不是方法里的原因是,这使得值是被动的,如果namesArray现在获得了另一个元素,整个列表就会被正确地重命名一次。方法并不能正确地做到这一点.我们创建一个namesArray的 "副本",以不触及对象本身的数据,因为这也会触发一次重新渲染。

在Vue中,你现在可以这样做。

<ul>
    <li v-for="(namesList, index) in sortedNames" :key="index">
        {{namesList.firstName}}
    </li>
</ul>

不排序的原因是 "string'-'string'=NaN "在javascript中,所以我用localeCompare替换了它。


1
投票

这里有几个问题:-

  1. 你不应该修改 this.namesArray 里面 computed 因为当它的一些被动依赖发生变化时,计算的属性会重新评估。这可能会产生副作用,因为项目可能会被插入到 this.namesArray 多次。
  2. 所以,更新 this.namesArray 里面 created 办法
  3. 并简单地将数组按 firstName 里面 addNamesToArray 的计算属性,用 localeCompare() 这样的方法。

new Vue({
  el: "#myApp",
  data() {
    return {
      namesArray: []
    }
  },
  created() {
    this.namesArray.push({"firstName": 'Charles',"lastName": 'Charleston'})
    this.namesArray.push({"firstName": 'Albert',"lastName": 'Alberterson'})
    this.namesArray.push({"firstName": 'Bertrand',"lastName": 'Doe'})
  },
  computed: {
    addNamesToArray() {
      return this.namesArray.sort((a, b) => a.firstName.localeCompare(b.firstName))
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
  <ul>
    <li v-for="(namesList, index) in addNamesToArray" :key="index">
      {{namesList.firstName}}
    </li>
  </ul>
</div>

0
投票

你可以试试这样的方法,因为它是: 计算的 它将更新时 this.namesArray 更新。

computed: {
    sortedNamesArray() {
        return this.namesArray.sort((a,b) => a.firstName - b.firstName);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.