使用vue过滤表行

时间:2019-01-27 22:07:33

标签: javascript vuejs2

我是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标记中选择的列:

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

我希望我有道理。我不知道如何从这里开始。 Cookies,非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

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

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>