【问题标题】:Sort props array on child component Vue.js在子组件Vue.js上对道具数组进行排序
【发布时间】:2020-01-28 23:51:14
【问题描述】:

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

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

我要做的是根据使用 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>

【问题讨论】:

    标签: javascript vue.js vue-component


    【解决方案1】:

    你有两个问题:

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

    【讨论】:

    • 对不起,我没有完全理解你的解释。当您提到第一部分时,我如何转换来自父组件并显示在可以在排序函数内部使用的对象的表格上的道具?
    • 如果我尝试以这种方式直接执行函数,则会引发排序未定义错误:job.applications OR this.job.applications > 然后 .sort...函数的其余部分
    • 我看到了你的 cmets,但我看到你接受了答案。您是否设法使其工作或您需要更多说明?老实说,我不是 100% 理解你的问题。
    猜你喜欢
    • 2019-03-27
    • 2020-06-25
    • 1970-01-01
    • 2020-03-31
    • 2018-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    相关资源
    最近更新 更多