首页 > 解决方案 > 使用 vue 过滤表行

问题描述

我是 vuejs 的新手。我有这张桌子:

<table>
 <thead>
    <tr
      v-for="(items, index) in data"
      v-if="index == 0">
      <td v-for="(item, key) in items">
        {{ key }}
      </td>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(items, index) in filteredData">
      <td v-for="item in items">
        {{ item }}
      </td>
    </tr>
  </tbody>
</table>

我想过滤行并显示与此输入中的任何内容匹配的行:

<input
  type="text"
  placeholder="Search something..."
  v-model="searchQuery">

我已经使用计算属性成功地做到了这一点。

computed: {
  filteredData: function() {
    return this.data.filter((items) => {
      for (var item in items) {
        if(String(items[item]).indexOf(this.searchQuery) !== -1) {
          return true
        }
      }
      return false
    })
  }
},

这将过滤表并仅显示具有与输入中的任何内容匹配的单元格的行。这完美地工作。

但是,现在我想过滤并仅显示其单元格与输入中的内容匹配的行,但仅搜索从我在下面创建的选择标记中选择的列:

<select
  id="columnsSelect"
  v-model="selected">
  <option
    v-for="column in columns"
    :value="column">
    {{ column }}
  </option>
</select>

我希望我说得通。我不知道如何从这里开始。饼干,非常感谢任何提供帮助的人!

标签: javascriptvuejs2

解决方案


您在使用计算属性进行过滤方面走在了正确的轨道上,现在您只需要添加逻辑以根据所选列过滤行。例如:

new Vue({
  el: '#app',
  data: () => ({
    search: null,
    column: null,
    items: []
  }),
  beforeMount () {
    this.items = Array.from(Array(20), (x,i) => {
      return {
        id: i,
        name: Math.random().toString(36).substring(7),
        title: Math.random().toString(36).substring(7),
        description: Math.random().toString(36).substring(7)
      }
    })
  },
  computed: {
    cols () {
      return this.items.length >= 1 ? Object.keys(this.items[0]) : []
    },
    rows () {
      if (!this.items.length) {
        return []
      }
      
      return this.items.filter(item => {
        let props = (this.search && this.column) ? [item[this.column]] : Object.values(item)
        
        
        return props.some(prop => !this.search || ((typeof prop === 'string') ? prop.includes(this.search) : prop.toString(10).includes(this.search)))
      })
    }
  }
})
* {
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
}

#app {
  width: 20rem;
}

#app > div {
  display: flex;
  flex-direction: row;
}

select, input {
  width: 50%;
}

table {
  width: 100%;
  border: 1px solid black;
  text-align: center;
  border-spacing: 0;
}

td {
  border-top: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div>
  <select v-model="column">
    <option :value="null">No Column Filter</option>
    <option v-for="col in cols" :key="col">{{ col }}</option>
  </select>
  <input type="text" v-model="search" placeholder="Search">
  </div>
  <table>
    <thead>
      <tr>
        <th v-for="col in cols" :key="col">{{ col }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="row in rows" :key="row.id">
        <td v-for="col in cols" :key="col">{{ row[col] }}</td>
      </tr>
    </tbody>
  </table>
</div>


推荐阅读