VueJs - таблица разбиения на страницы и фильтр

я использую Vue2.js и Element UI в качестве основы. Я хотел бы иметь возможность фильтр таблица, которая отрезанный. Для этого я использую table и filter компоненты, описание которых можно найти здесь.

ситуация OK

стол не нарезан. Когда вы выбрали фильтр, цикл проходит через каждую строку и проверяет, равно ли значение столбца фильтру.

ситуация не OK

стол нарезан. Когда вы выбрали фильтр, цикл проходит через каждую строку, которая приводит к срезу, и проверяет, равно ли значение столбца фильтру. При этом мы не фильтруем "скрытые" значения.

Я сделал немного https://jsfiddle.net/acm3q6q8/3/ так легче понять.

все это имеет смысл, так как я работаю не над всеми данными, а над нарезанной версией.

одним из решений может следует скрывать строки, а не исключать их, нарезая данные, но мне интересно, есть ли лучшее решение ?

чего я хочу добиться

  • на jsfiddle показывать только 2 вещи.
  • фильтр tag для отображения только строк, тег которого Office

фактический результат

нет строки, отображаемой с строки, чья tag был офис не был частью нарезанного стола.

ожидается результат

при фильтрации я хотел бы учитывать строки, которые не обязательно отображаются.

важно

это должно работать нормально с несколькими фильтрами (т. е. Я выбираю несколько тегов)

редактировать

в той же степени, если вы хотите отсортировать имя по алфавиту, Альберт не будет отображаться, если вы отобразили только 2 элемента.

2 ответов


вы можете справиться с filter-change событие в компоненте таблицы (документировано здесь), и фильтр/порезаться.

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>

пример.


проблема в том, что нарезка делается до фильтрации. Фильтр должен видеть исходные данные, и подсчет строк должен быть частью фильтрации.

поскольку фильтр смотрит на одну строку за раз, отслеживание совпадающих строк немного сложно. То, что я сделал здесь, - это сохранить счетчик совпадающих строк, который сбрасывается до нуля, когда рассматриваемая строка является первой строкой данных. Это hacky, но это работает. Может быть, есть лучший способ; я не знаком со столом штучка.

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')
@import url("//unpkg.com/element-ui/lib/theme-default/index.css");
<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>