VueJs - 表格分页和过滤

时间:2017-04-17 18:15:04

标签: javascript vue.js vuejs2

我正在使用Vue2.jsElement UI作为框架。我希望能够过滤 切片的表格。为此,我使用了tablefilter组件,其文档可以找到here

情况确定

表格未切片。当你选择一个过滤器时,循环遍历每一行并检查列的值是否等于过滤器。

情况不行

桌子被切成薄片。当您选择过滤器时,循环将通过切片结果的每一行,并检查列的值是否等于过滤器。通过这样做,我们不会过滤“隐藏”值。

我做了一点https://jsfiddle.net/acm3q6q8/3/因此更容易理解。

所有这一切都有意义,因为我不是在处理整个数据,而是在切片版本上。

一种解决方案可能是隐藏行而不是通过切片数据来排除它们,但我想知道是否有更好的解决方案?

我想要实现的目标

  • jsfiddle中,仅显示2个项目。
  • 过滤tag以仅显示标记为Office
  • 的行

实际结果

由于tag所在的行不是切片表的一部分,因此没有显示任何行。

预期结果

过滤时,我想考虑不一定要显示的行。

重要

这应该适用于多重过滤器(即我选择几个标签)

修改

如果您想按字母顺序对名称进行排序,如果您只显示2个项目,则不会显示Albert。

2 个答案:

答案 0 :(得分:2)

您可以处理表格组件上的filter-change事件(记录为here),并自行过滤/切片。

var Main = {
    data() {
      return {
        numberItemToShow : 4,
        tableData: [...],
        filter: []
      }

    },
    computed : {
      filterData() {
          if (!this.filter.length)
            return this.tableData.slice(0, this.numberItemToShow)
          else
            return this.tableData
              .filter(row => this.filter.includes(row.tag))
              .slice(0, this.numberItemToShow);
      }
    },
    methods: {
      onFilterChange(filters){
        if (filters.tag)
            this.filter = filters.tag;
      }
    }  
}

和模板

<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
  <el-table ref="tab" :data="filterData" border style="width: 100%" @filter-change="onFilterChange">
    <el-table-column prop="name" label="Name"   sortable>
    </el-table-column>
    <el-table-column prop="tag" label="Tag" column-key="tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]">
      <template scope="scope">
        <el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
      </template>
    </el-table-column>
  </el-table>
</template>

Example

答案 1 :(得分:1)

问题是切片是在过滤之前完成的。过滤器必须查看原始数据,行计数必须是过滤的一部分。

由于过滤器一次查看一行,因此跟踪匹配的行有点棘手。我在这里做的是保持匹配行的计数器,当被查看的行是第一行数据时,这些行重置为零。这很hacky,但它确实有效。可能有更好的方法;我不熟悉表格小部件。

&#13;
&#13;
var Main = {
    data() {
      return {
      	numberItemToShow : 4,
        tableData: [{
          name: 'One',
          tag: 'Home'
        }, {
          name: 'Two',
          tag: 'Home'
        }, {
          name: 'Three',
          tag: 'Home'
        }, {
          name: 'Four',
          tag: 'Office'
        }],
        scratchCounter: 0
      }
    },
    methods: {
      filterTag(value, row) {
        const matched = row.tag === value;

        if (row === this.tableData[0]) {
        	this.scratchCounter = 0;
        }
        if (matched) {
        	++this.scratchCounter;
        }
        return this.scratchCounter <= this.numberItemToShow && matched;
      }
    }
  }
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
&#13;
@import url("//unpkg.com/element-ui/lib/theme-default/index.css");
&#13;
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui/lib/index.js"></script>
<div id="app">
<template>
<input v-model="numberItemToShow" placeholder="edit me">
<p>Number of item to display: {{ numberItemToShow }}</p>
  <el-table :data="tableData" border style="width: 100%">
    <el-table-column prop="name" label="Name">
    </el-table-column>
    <el-table-column prop="tag" label="Tag" :filters="[{ text: 'Home', value: 'Home' }, { text: 'Office', value: 'Office' }]" :filter-method="filterTag">
      <template scope="scope">
        <el-tag :type="scope.row.tag === 'Home' ? 'primary' : 'success'" close-transition>{{scope.row.tag}}</el-tag>
      </template>
    </el-table-column>
  </el-table>
</template>
</div>
&#13;
&#13;
&#13;