如何使用 vutify 的自定义排序?

Posted

技术标签:

【中文标题】如何使用 vutify 的自定义排序?【英文标题】:How to use vutify's custom sort? 【发布时间】:2019-03-11 17:53:43 【问题描述】:

我想在我的数据表中使用custom-sort。我的目标是对表 DESC 进行排序,而不是对默认 ASC 进行排序。但我不知道怎么做。

这是我的数据表组件的开始:

  <v-data-table
  :headers="headers"
  :items="acts"
  hide-actions
  class="elevation-1"
  >
  <template slot="items" slot-scope="props">

    <td> props.item.id </td>
    <td> props.item.name </td>
    <td class="text-xs-center"> props.item.provider.id </td>
    <td class="text-xs-center"> props.item.category.name </td>
    <td class="text-xs-center"> props.item.budget </td>
    <td class="text-xs-center"> props.item.location.name </td>
    <td class="text-xs-center"> props.item.deets </td>
    <td class="text-xs-center"> props.item.keeping_it_100 </td>
    <td class="text-xs-center"><img   :src="props.item.inspiration.inspiration"></td>
    <td class="justify-center layout px-0">....

这是我正在使用的脚本:

<script>
  export default 
    data () 
      return 

        dialog: false,
        customerSort: 
          isDescending: true,// I tried this? as the kabab format throws an error
        ,
        headers: [
             text: 'ID', value: 'id',
             text: 'Name', value: 'name' ,  
             text: 'Provider', value: 'provider' ,
             text: 'Category', value: 'category' ,
             text: 'Budget', value: 'budget' ,
             text: 'Country', value: 'location', sortable: true ,
             text: 'Keeping it 100%', value: 'keeping_it_100', sortable: false ,
             text: 'deets', value: 'deets', sortable: false ,
             text: 'inspiration', value: 'inspiration', sortable: false ,
             text: 'Cover', value: 'cover', sortable: false ,
             text: 'Actions', value: 'actions', sortable: false 
        ],

根据文档,它是function prop。但是我还没有找到如何通过的例子。

This is a screenshot of the function...

【问题讨论】:

【参考方案1】:

你可以使用这样的函数-

customSort(items, index, isDesc) 
  items.sort((a, b) => 
    if (index === "date") 
      if (!isDesc) 
        return compare(a.date, b.date);
       else 
        return compare(b.date, a.date);
      
    
  );
  return items;

其中 compare 是一个比较 a.date 和 b.date 的函数,返回 1-1

isDesc 是一个由表传递的变量,它告诉用户想要以什么顺序对其进行排序。如果要按 desc 排序,只需在 if-else 条件中使用 !isDesc

要在您的模板中使用它,只需使用

<v-data-table
  :headers="headers"
  :items="Data"
  :custom-sort="customSort"
>
  <template slot="items" slot-scope="props">
    <td class="font-weight-black"> props.item.date </td>
    <td class="text-xs-right"> props.item.time </td>
    <td class="text-xs-right"> props.item.name </td>
  </template>
</v-data-table>

为了确保您的其他字段仍然可以正常排序使用

customSort(items, index, isDesc) 
      items.sort((a, b) => 
        if (index === "date") 
          if (!isDesc) 
            return dateHelp.compare(a.date, b.date);
           else 
            return dateHelp.compare(b.date, a.date);
          
         else 
          if (!isDesc) 
            return a[index] < b[index] ? -1 : 1;
           else 
            return b[index] < a[index] ? -1 : 1;
          
        
      );
      return items;
    

【讨论】:

你需要检查 index[0] == "date" 这适用于以前版本的 Vue 或仅按 1 列排序的新版本。对于multi-sortgroup-by,您按多列排序,这会中断。有谁知道这个功能可能记录在哪里?【参考方案2】:

基于this answer关于custom-filter的代码,我尝试使用custom-sort。 如果您将其应用于您的代码,请参考此答案。

通过以下代码,当我点击“卡路里”标题时,我已确认排序。My CodePen

new Vue(
    el: '#app',
    data() 
        return 
            food: [
                 name: 'Bakchoi', type: 'vegetable', calories: 100 ,
                 name: 'Pork', type: 'meat', calories: 200 ,
                 name: 'Chicken Thigh', type: 'meat', calories: 300 ,
                 name: 'Watermelon', type: 'fruit', calories: 10 ,
            ],
            headers: [
                 text: 'Name', align: 'left', value: 'name' ,
                 text: 'Food Type', align: 'left', value: 'type' ,
                 text: 'Calories', align: 'left', value: 'calories' ,
            ],
            search: '',

        ;
    ,
    methods: 
        customSort(items, index, isDescending) 
          // The following is informations as far as I researched.
          // items: 'food' items
          // index: Enabled sort headers value. (black arrow status).
          // isDescending: Whether enabled sort headers is desc
          items.sort((a, b) => 
              if (index === 'calories') 
                  if (isDescending) 
                      return b.calories - a.calories;
                   else 
                      return a.calories - b.calories;
                  
              
          );

          return items;
        
    
)
<script src="https://unpkg.com/vue@2.4.2/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@0.15.2/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify@0.15.2/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">

<div id="app">
    <v-app>
        <v-select
                label="Food Type"
                :items="['vegetable', 'meat', 'fruit']"
                v-model="search"
        ></v-select>

        <v-data-table
                :headers="headers"
                :items="food"
                :search="search"
                :custom-sort="customSort"
                hide-actions
        >
            <template slot="items" scope=" item ">
                <td> item.name </td>
                <td> item.type </td>
                <td> item.calories </td>
            </template>
        </v-data-table>
    </v-app>
</div>

【讨论】:

【参考方案3】:

注意:以下答案适用于 Vuetify 1.5.x

在这里聚会有点晚了,如果您只想按单个字段降序排序,那么自定义排序不是您想要使用的,您最好使用 :pagination.sync 道具

当您想要更改比较函数的行为时使用自定义排序(例如,根据字符串的反向或小写版本进行排序,或以“DD-MM-YYYY”格式对日期字符串进行正确排序)。

如果您想使用默认的降序功能,请使用 :pagination.sync 属性,如下所示:

<v-data-table
  :headers="headers"
  :items="acts"
  :pagination.sync="pagination"
>
    <template v-slot:items="props">...</template>
</v-data-table>

在你的脚本中,设置pagination:

data () 
  return 
    pagination: 
      sortBy: 'id', // The field that you're sorting by
      descending: true
    
  

这指定您希望表格最初按 id 降序排序 - id 可以更改为数据集中的任何字段名称。

值得注意的是,这仅指定了默认行为,如果您为其他标题启用了排序,用户仍然可以按任何字段对表格进行排序。

【讨论】:

【参考方案4】:

以bhaskar提供的响应为基础

为了在 vuetify 2.x 上工作,我必须将最后一个代码示例编辑为以下内容。该代码按存储在time_stamp 键下的纪元时间对日期列进行排序。该代码还允许对数字和字符串进行默认排序(字符串按字母顺序排序)

        customSort(items, index, isDesc) 
        items.sort((a, b) => 
            if (index[0] == "date") 
                if (!isDesc[0]) 
                    return a.time_stamp - b.time_stamp;
                 else 
                    return b.time_stamp - a.time_stamp;
                
             else if (!(isNaN(a[index[0]]))) 
                if (!isDesc[0]) 
                    return (a[index[0]] - b[index[0]]);
                 else 
                    return (b[index[0]] - a[index[0]]);
                

             else 
                if (!isDesc[0]) 
                    return (a[index[0]] < b[index[0]]) ? -1 : 1;
                 else 
                    return (b[index[0]] < a[index[0]]) ? -1 : 1;
                
            
        );
        return items;
    

【讨论】:

【参考方案5】:

在 vuetify 2 中只需使用 sortBy="date" 并更新:sort-desc

<v-data-table
  :headers="headers"
  :items="acts"
  :pagination.sync="pagination"
  sortBy="date"
  update: sort-desc
 >

【讨论】:

这个语法对于 update 属性来说看起来很奇怪。你有这个工作的例子吗? @bigsee 我不再使用 vue,检查他们的文档,他们一直在更新 vuetify,所以一年前有效的东西,今天可能不起作用【参考方案6】:

虽然这是一个老问题......

对于只有一列的特殊排序,您可以使用 headers 数组中的属性 sort。 另见https://vuetifyjs.com/en/api/v-data-table/#headers

像这样:

// in data ... 
headers: [
... 

    text: "Date",
    sortable: true,
    value: "date",
    sort: (a, b) => a.time_stamp - b.time_stamp
 ,
 ...
]

像这样使用它

<v-data-table
 :headers="headers"
...
>

【讨论】:

以上是关于如何使用 vutify 的自定义排序?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server的自定义排序功能

STL中的自定义排序

如何使用 MongoDB 中的自定义字段对分页进行索引和排序,例如:名称而不是 id

在 XAML 中调用时,如何使我的自定义依赖项属性排序到顶部?

asp.net 如何方便,快速的实现,好像excel那样的自定义排序与自定义筛选功能。

laravel 关系集合上的自定义排序