Сортировать массив реквизитов на дочернем компоненте Vue.js - PullRequest
1 голос
/ 29 сентября 2019

Я пытаюсь отсортировать массив объектов, полученных из реквизита дочернего компонента.

Однако мой метод сортировки 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 голосов
/ 30 сентября 2019

У вас там две проблемы:

1.Неправильно Метод доступа к свойству

Вы используете точечную запись в своей функции сортировки, что означает, что вы пытаетесь получить доступ к буквальному свойству sortBy ваших объектов.

Вместо этого вам нужна скобочная нотация , которая позволяет передавать переменную в метод доступа и, таким образом, получать динамически установленное свойство.Например,

const obj = {
 prop1: "value"
};

const myProp = "prop1";

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

2.Неправильная функция сравнения

Вы вычитаете две строки друг из друга, что возвращает NaN.Функция сортировки не может работать так.Вместо этого функция сравнения должна возвращать либо 0, либо меньше 0, либо больше 0.

Дополнительная информация здесь (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;
    });
}

Extra

Я вижу в вашем коде, что вы хотите добавить порядок сортировки, но он не реализован в функции.Вы можете сделать:

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;
    });
}
...