【问题标题】:Sort table Vue.js排序表Vue.js
【发布时间】:2020-04-23 15:27:39
【问题描述】:

我正在尝试按列对表格进行排序。按下 ID 按钮时,所有列从高到低排序,反之亦然,按下其他两个按钮也是如此。我该怎么做?

<table id="mi-tabla">
            <thead>
            <tr class="encabezado-derecha" >
              <th>ID</th>
              <th>Nombre de sección</th>
              <th>Potencial (€)</th>
            </tr>
            </thead>
            <tbody>
            <tr class="item" v-for="user in userInfo" @click="openDiv(), showInfo1(user.id_section)">
              <td>{{user.id_section}}</td>
              <td>{{user.desc_section}}</td>
              <div class="acceder">
              <td>{{user.sale_potential | currency}}</td>
              <img src="../../iconos/icon/chevron/right@3x.svg" alt />
              </div>
            </tr>
            </tbody>
          </table>

{
      "id_store": 4,
      "id_section": 1,
      "desc_section": "MATERIALES DE CONSTRUCCION yeh",
      "id_rule": 1,
      "sale_potential": "69413.5525190617"
    },
    {
      "id_store": 4,
      "id_section": 2,
      "desc_section": "CARPINTERIA Y MADERA",
      "id_rule": 1,
      "sale_potential": "74704.3439572555"
    },
    {
      "id_store": 4,
      "id_section": 3,
      "desc_section": "ELECTR-FONTAN-CALOR",
      "id_rule": 1,
      "sale_potential": "101255.89182774"
    }
    ]

【问题讨论】:

  • 您想自己制作功能,还是只使用已经完成的现有组件?
  • 我想自己做。

标签: sorting vue.js vuejs2 vue-component


【解决方案1】:

如果您想自己实现它可能会是这样,请注意这是非常基本的功能,当您开始添加其他功能时,您可能会看到使用已经完成所有功能的组件会带来更多好处。

无论如何,您可以使用计算的 (sortedList) 来存储数组的排序版本。然后使用另一个数据变量来存储您要存储的列(sortBy),并且可以选择存储排序方向(sortOrder

然后添加一个sort 方法,该方法传递排序键并更新sortBy 值和/或sortOrder。当这些值中的任何一个(甚至是源数组)发生变化时,computed 将使用 sort 函数对数组进行重新排序。

new Vue({
  el: "#app",
  data: {
  	sortBy: "id_section",
    sortOrder: 1,
    userInfo: [
      {
        "id_store": 4,
        "id_section": 1,
        "desc_section": "MATERIALES DE CONSTRUCCION yeh",
        "id_rule": 1,
        "sale_potential": "69413.5525190617"
      },
      {
        "id_store": 4,
        "id_section": 2,
        "desc_section": "CARPINTERIA Y MADERA",
        "id_rule": 1,
        "sale_potential": "74704.3439572555"
      },
      {
        "id_store": 4,
        "id_section": 3,
        "desc_section": "ELECTR-FONTAN-CALOR",
        "id_rule": 1,
        "sale_potential": "101255.89182774"
      }
    ]
  },
  computed: {
    sortedList() {
      return [...this.userInfo]
        .map(i => ({...i, sale_potential:parseFloat(i.sale_potential)}))
        .sort((a,b) => {
      	  if (a[this.sortBy] >= b[this.sortBy]) {
        	return this.sortOrder
          }
        return -this.sortOrder
      })
    }
  },
  methods: {
  	sort: function(sortBy){
    	if(this.sortBy === sortBy) {
      	this.sortOrder = -this.sortOrder;
      } else {
      	this.sortBy = sortBy
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  [{{sortBy}}] [{{sortOrder}}]
  <table id="mi-tabla">
    <thead>
      <tr class="encabezado-derecha">
        <th @click='sort("id_section")'>{{ sortBy === 'id_section' ? '*' : '' }}ID</th>
        <th @click='sort("desc_section")'>{{ sortBy === 'desc_section' ? '*' : '' }}Nombre de sección</th>
        <th @click='sort("sale_potential")'>{{ sortBy === 'sale_potential' ? '*' : '' }}Potencial (€)</th>
      </tr>
    </thead>
    <tbody>
      <tr class="item" v-for="user in sortedList">
        <td>{{user.id_section}}</td>
        <td>{{user.desc_section}}</td>
        <div class="acceder">
          <td>{{user.sale_potential | currency}}</td>
          <img src="../../iconos/icon/chevron/right@3x.svg" alt />
        </div>
      </tr>
    </tbody>
  </table>
</div>

【讨论】:

  • 我删除了@click ion td,但它仍然可以使用
  • 但不按字母顺序或数字从高到低排序
  • 对,? 我忘了包括那部分。需要在排序中使用像这样a[this.sortBy] &gt;= b[this.sortBy]更新代码的键。
  • 现在如果它有效,唯一的问题是第三列(潜在)没有按数字排序。谢谢!!
  • 这就是我们进入微调问题的地方。原因是排序是在字符串值上完成的。所以排序函数需要知道,仅对于该列,才能转换为数字。我处理的方式是我有一个包含此类信息的表配置(以及许多其他内容,例如为给定列格式化每一行的函数)。但在这种情况下,您可以在对其进行排序之前将其转换为 sortedList 中计算的数值。我已经用示例更新了答案。
【解决方案2】:

我建议您使用带有过滤和排序功能的引导 Vue 表。您所要做的就是将数据传递到表中。

这里有一个链接,你可以看看。

https://bootstrap-vue.js.org/docs/components/table#complete-example

< script >
  export default {
    data() {
      return {
        items: [{
            "id_store": 4,
            "id_section": 1,
            "desc_section": "MATERIALES DE CONSTRUCCION yeh",
            "id_rule": 1,
            "sale_potential": "69413.5525190617"
          },
          {
            "id_store": 4,
            "id_section": 2,
            "desc_section": "CARPINTERIA Y MADERA",
            "id_rule": 1,
            "sale_potential": "74704.3439572555"
          },
          {
            "id_store": 4,
            "id_section": 3,
            "desc_section": "ELECTR-FONTAN-CALOR",
            "id_rule": 1,
            "sale_potential": "101255.89182774"
          }
        ],
        fields: [{
          key: 'id_store',
          label: 'id',
          sortable: true
        }, {
          key: 'desc_section',
          label: 'Nombre de sección'
        }, {
          key: 'sale_potential'
        },{key:'actions'}]
      }
    },
  } <
  /script>
   <b-table striped hover :items="items" :fields="fields">
    <template v-slot:cell(sale_potential)="row">
           <p>{{row.item.sale_potential |currency}}</p>
         <img src="../../iconos/icon/chevron/right@3x.svg" alt />
     </template> 
   <template v-slot:cell(actions)="row">
     <button @click="openDiv(); showInfo1(row.item.id_section);" 
         class="btn" variant="primary">Action</button>
    </template> 
  </b-table>

【讨论】:

  • 问题是我在 sale_potential 中添加了一个过滤器,以便它分隔数千并添加货币符号,并且在 tbody 中它有一个无法以引导方式添加的点击事件。跨度>
  • 对于过滤器,您可以使用插槽。让我更新答案。点击事件应该做什么?
  • 事件做了两件事,'openDiv ()' 打开了一个新的 div,其中显示了一个列表,通过选择 id_section 'showInfo1 (user.id_section )'
  • 好的,我们可以通过一个插槽在行中添加一个按钮,单击该按钮会执行上述事件。让我将其添加到答案中。希望它能回答你的问题。
【解决方案3】:

如果您想自己添加此功能,您可以使用计算值对数据进行排序来实现它。

data () => ({
  ...
  sortBy : null,
}),
computed : {
  userInfoSorted () {
    const sortBy = this.sortBy
    if (!sortBy) return this.userInfo
    return this.userInfo.sort((a,b)=> a[sortBy] > b[sortBy] ? 1 : -1)
  }
}

然后更新您模板中&lt;th&gt; 标记中的sortBy 值:

<th @click="sortBy='id_section'">ID</th>

并将您的行链接到计算值:

<tr class="item" v-for="user in userInfoSorted">

编辑:更改排序顺序

要添加切换顺序的选项,首先将标题添加到您的数据对象:

data () => ({
  ...
  headers : {
    id_section : {
       text : 'ID',
       reverse : true
    }
  }
})

然后更新您的模板以更改点击时的反向值:

  <th v-for="(val,key) in headers" @click="sortBy=key; val.reverse=!val.reverse">
   {{ val.text }}
  </th>

最后在你的排序函数中包含反向值:

userInfoSorted () {
    const sortBy = this.sortBy
    const r = this.headers[sortBy].reverse ? -1 : 1;
    if (!sortBy) return this.userInfo
    return this.userInfo.sort((a,b)=> a[sortBy] > b[sortBy] ? 1*r : -1*r)
  }

【讨论】:

  • 谢谢!!它有效,但是当第二次按下它时,你会怎么做呢?它是从高到低排序的
  • 并且不按字母顺序排列第二列
  • 我已经更新了答案,展示了如何切换顺序并更改排序功能,使其适用于字母。
猜你喜欢
  • 2018-02-04
  • 2019-03-16
  • 2018-10-14
  • 2017-09-30
  • 1970-01-01
  • 2018-12-23
  • 2017-07-31
  • 2019-07-25
  • 1970-01-01
相关资源
最近更新 更多