在子组件Vue.js上对props数组进行排序

时间:2019-09-29 12:15:19

标签: javascript vue.js vue-component

我正在尝试对来自子组件上的道具的对象进行排序。

但是,我的排序方法Throw出现错误。也许我没有正确使用该方法,或者我无法正确确定需要传递给它的参数。

我想做的是根据使用click函数传递的参数进行排序,并调用一种方法来执行排序。

这里的目的是当我单击名称上的箭头时,然后可以根据箭头(asc或desc)按名称对它进行排序。

这是我的组件ApplicationsList.vue

<template>
    <div class="modal-backdrop">
    <div class="modal">
      <header class="modal-header">
        <slot name="header">
          <h3>{{job.name}}</h3>

          <button v-if="application.name" type="button" class="btn-close" @click="back">
            <i class="fa fa-arrow-left"></i> Back
          </button>
          <button type="button" class="btn-close" @click="close">
            x
          </button>
        </slot>
      </header>
      <section class="modal-body">
          <div class="row">
              <div v-if="!application.name" class=" col-12 applications-list">
                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th>Name &nbsp;
                                <i @click="changeSort('name', 'desc')" v-if="this.sortBy === 'name' && this.sortDirection === 'asc' " class="fa fa-sort-up"></i>
                                <i @click="changeSort('name', 'asc')" v-if="this.sortBy === 'name' && this.sortDirection === 'desc' " class="fa fa-sort-down"></i>
                            </th>
                            <th>Email &nbsp;<i class="fa fa-unsorted"></i></th>
                            <th>Date &nbsp;<i class="fa fa-unsorted"></i></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="application-row" v-for="application in job.applications" :key="application.id" :application="application" @click="getApplication(application)">
                            <td>{{application.name}}</td>
                            <td>{{application.email}}</td>
                            <td>Applied {{moment(application.created_at).fromNow()}}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div v-if="application.name" class="col-12 applicant">
                <small>Applied {{moment(application.created_at).fromNow()}}</small>
                <h4 v-if="application.name">Name</h4><p>{{application.name}}</p>
                <h4 v-if="application.email">Email</h4><p>{{application.email}}</p>
                <h4 v-if="application.phone">Phone</h4><p>{{application.phone}}</p>
                <h4 v-if="application.linkedin">Linkedin</h4><p>{{application.linkedin}}</p>
                <h4 v-if="application.cover_letter">Coverletter</h4><p v-html="application.cover_letter"></p>
            </div>
          </div>
      </section>
      <footer class="modal-footer">
    </footer>
  </div>
</div>
</template>


<script>

import moment from 'moment';

export default {

    name: 'ApplicationsList',

    props:['job'],

    data(){
        return{
            application: {name:'', email: '', created_at:'', phone: '', linkedin: '', cover_letter: ''},
            sortBy:'name',
            sortDirection:'asc',
        }
    },

    methods:{

        moment,

        close(){
            this.$emit('closeApplicationsRequest');
        },

        getApplication(application){
            this.application = application;
        },

        back(){
            this.application = '';
        },

        changeSort(sortBy, sortDirection){

            return this.job.application.sort((a, b) => a.sortBy - b.sortBy)

        }

    },


}

</script>

1 个答案:

答案 0 :(得分:0)

您在那里遇到了两个问题:

1。错误的Property accessor

您在排序函数上使用了点符号,这意味着您正在尝试访问对象的文字sortBy属性。

您想要的是括号符号,它允许您将变量传递给访问器,并因此获得动态设置的属性。例如

const obj = {
 prop1: "value"
};

const myProp = "prop1";

obj.myProp; // undefined;
obj[myProp]; // "value"   

2。比较功能错误

您要相互减去两个字符串,这将返回NaN。排序功能不能像这样工作。相反,比较函数需要返回0,小于0或大于0。

More information here (MDN)

工作代码

function changeSort(sortBy) {
  return this.job.application
    .sort((a, b) => {
      if(a[sortBy] < b[sortBy]) return -1;
      if(a[sortBy] > b[sortBy]) return 1;
      return 0;
    });
}

额外

我在您的代码中看到您想要添加排序顺序,但是该功能未实现。您可以这样做:

function changeSort(sortBy, sortDirection) {
  const alphabeticalApplications = this.job.application
    .sort((a, b) => {
      if(a[sortBy] < b[sortBy]) return -1;
      if(a[sortBy] > b[sortBy]) return 1;
      return 0;
    });

  return sortDirection === "asc" ? alphabeticalApplications
   : alphabeticalApplications.reverse();
}

function changeSort(sortBy, sortDirection) {
  const sortMultiplier = sortDirection === "asc" ? 1 : -1;
  return this.job.application
    .sort((a, b) => {
      if(a[sortBy] < b[sortBy]) return -1 * sortMultiplier;
      if(a[sortBy] > b[sortBy]) return 1 * sortMultiplier;
      return 0;
    });
}