【问题标题】:Filter search with computed in vue.js 3在 vue.js 3 中使用计算过滤搜索
【发布时间】:2022-01-25 12:08:40
【问题描述】:

我有这个搜索输入:

<input
class="form-control"
type="text"
name="search"
placeholder="search..."
v-model="search"
/>

还有这个“输出”区域:

<my-comp
v-for="item in filter"
:key="item.id"
:id="item.id"
:imgsrc="item.imgsrc"
:price="item.price"
:city="item.city"
:country="item.country"
:reviewnum="item.reviewnum"
:daynum="item.daynum"
/>

我从 json 文件中取出数据 这是数据

[
    {"id": 1, "city":"California", "country": "United State of America", "price": "700", "reviewnum": "890", "daynum": "5", "imgsrc": "img/place/1.png"},
    {"id": 2, "city":"london", "country": "United Kingdom", "price": "550", "reviewnum": "900", "daynum": "4", "imgsrc": "img/place/2.png"},
    {"id": 3, "city":"Korola Megna", "country": "Nepal", "price": "350", "reviewnum": "150", "daynum": "5", "imgsrc": "img/place/3.png"},
    {"id": 4, "city":"Miami Beach", "country": "United State of America", "price": "850", "reviewnum": "660", "daynum": "7", "imgsrc": "img/place/4.png"},
    {"id": 5, "city":"California", "country": "United State of America", "price": "600", "reviewnum": "380", "daynum": "6", "imgsrc": "img/place/5.png"},
    {"id": 6, "city":"Saintmartine Iceland", "country": "Kingdom of the Netherlands", "price": "450", "reviewnum": "340", "daynum": "3", "imgsrc": "img/place/6.png"}
]

这个想法是用户搜索一个城市或国家或任何数据,输出应该只显示他正在搜索的卡片。

这是vue js代码:

import data from "@/assets/data.json";

export default {
  name: "Home",
  data: function () {
    return {
      allData: data,
      search: "",
    };
  },
  components: { myComp, foooter, headeer },
  computed: {
    filter() {
      if (!this.search) {
        return this.allData;
      } else {
        return this.allData.filter(({ country }) =>
          (country).toLowerCase().includes(this.search.toLowerCase())
        );
      }
    },
  },
};

但我的函数只接受一个变量。我该怎么办?

【问题讨论】:

  • 您要么将控制权交给用户并允许他们选择搜索的列,要么搜索所有列。
  • 顺便说一句,因为您使用的是 Options API,所以您的问题是 Vue2 特定的而不是 Vue3 特定的,即使这种语法也适用于 Vue 3。

标签: javascript vue.js search filter vuejs3


【解决方案1】:

搜索所有列:

computed: {
  filteredData() {
    return this.allData
      .filter(
        (entry) => this.allData.length
          ? Object.keys(this.allData[0])
              .some(key => ('' + entry[key]).toLowerCase().includes(this.search))
          : true
      );
  }
}

看看它的工作原理:

new Vue({
  el: '#app',
  data: () => ({
    search: '',
    allData: [
    {"id": 1, "city":"California", "country": "United State of America", "price": "700", "reviewnum": "890", "daynum": "5", "imgsrc": "img/place/1.png"},
    {"id": 2, "city":"london", "country": "United Kingdom", "price": "550", "reviewnum": "900", "daynum": "4", "imgsrc": "img/place/2.png"},
    {"id": 3, "city":"Korola Megna", "country": "Nepal", "price": "350", "reviewnum": "150", "daynum": "5", "imgsrc": "img/place/3.png"},
    {"id": 4, "city":"Miami Beach", "country": "United State of America", "price": "850", "reviewnum": "660", "daynum": "7", "imgsrc": "img/place/4.png"},
    {"id": 5, "city":"California", "country": "United State of America", "price": "600", "reviewnum": "380", "daynum": "6", "imgsrc": "img/place/5.png"},
    {"id": 6, "city":"Saintmartine Iceland", "country": "Kingdom of the Netherlands", "price": "450", "reviewnum": "340", "daynum": "3", "imgsrc": "img/place/6.png"}
]
  }),
  computed: {
    filteredData() {
      return this.allData
        .filter(
          (entry) => this.allData.length
            ? Object.keys(this.allData[0])
                .some(key => ('' + entry[key]).toLowerCase().includes(this.search))
            : true
        );
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
  <input type="search" v-model="search">
  <div v-for="entry in filteredData" :key="entry.id">
    <pre v-text="entry" />
  </div>
</div>

搜索特定列:

computed: {
  filteredData() {
    return this.allData
      .filter(
        ({ country, city }) => [country, city]
          .some(val => val.toLowerCase().includes(this.search))
      );
  }
}

看看它的工作原理:

new Vue({
  el: '#app',
  data: () => ({
    search: '',
    allData: [
    {"id": 1, "city":"California", "country": "United State of America", "price": "700", "reviewnum": "890", "daynum": "5", "imgsrc": "img/place/1.png"},
    {"id": 2, "city":"london", "country": "United Kingdom", "price": "550", "reviewnum": "900", "daynum": "4", "imgsrc": "img/place/2.png"},
    {"id": 3, "city":"Korola Megna", "country": "Nepal", "price": "350", "reviewnum": "150", "daynum": "5", "imgsrc": "img/place/3.png"},
    {"id": 4, "city":"Miami Beach", "country": "United State of America", "price": "850", "reviewnum": "660", "daynum": "7", "imgsrc": "img/place/4.png"},
    {"id": 5, "city":"California", "country": "United State of America", "price": "600", "reviewnum": "380", "daynum": "6", "imgsrc": "img/place/5.png"},
    {"id": 6, "city":"Saintmartine Iceland", "country": "Kingdom of the Netherlands", "price": "450", "reviewnum": "340", "daynum": "3", "imgsrc": "img/place/6.png"}
]
  }),
  computed: {
    filteredData() {
      return this.allData
        .filter(
          ({ country, city }) => [country, city]
            .some(val => val.toLowerCase().includes(this.search))
        );
      }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
  <input type="search" v-model="search">
  <div v-for="entry in filteredData" :key="entry.id">
    <pre v-text="entry" />
  </div>
</div>

第一个从第一个条目中获取所有键(如果您有任何数据)将所有值转换为字符串(因此它可以在其上运行 .toLowerCase())并检查 this.search 是否包含在该字段中保存的值中,每个条目。

第二个不太通用,因此更准确。当您确切知道要搜索哪些字段时,您可能希望使用它,以防止误报。


另一个选项是给用户一个下拉列表来选择他们想要过滤的列。

new Vue({
  el: '#app',
  data: () => ({
    searchTerm: '',
    searchColumn: 'id',
    allData: [
    {"id": 1, "city":"California", "country": "United State of America", "price": "700", "reviewnum": "890", "daynum": "5", "imgsrc": "img/place/1.png"},
    {"id": 2, "city":"london", "country": "United Kingdom", "price": "550", "reviewnum": "900", "daynum": "4", "imgsrc": "img/place/2.png"},
    {"id": 3, "city":"Korola Megna", "country": "Nepal", "price": "350", "reviewnum": "150", "daynum": "5", "imgsrc": "img/place/3.png"},
    {"id": 4, "city":"Miami Beach", "country": "United State of America", "price": "850", "reviewnum": "660", "daynum": "7", "imgsrc": "img/place/4.png"},
    {"id": 5, "city":"California", "country": "United State of America", "price": "600", "reviewnum": "380", "daynum": "6", "imgsrc": "img/place/5.png"},
    {"id": 6, "city":"Saintmartine Iceland", "country": "Kingdom of the Netherlands", "price": "450", "reviewnum": "340", "daynum": "3", "imgsrc": "img/place/6.png"}
]
  }),
  computed: {
    columns() {
      return Object.keys(this.allData[0]);
    },
    filteredData() {
      return this.allData
        .filter(
          entry => ('' + entry[this.searchColumn]).toLowerCase().includes(this.searchTerm)
        );
      }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
  Search <input type="search" v-model="searchTerm">
  in: <select v-model="searchColumn">
    <option v-for="column in columns" :value="column" :key="column" v-text="column" />
  </select>
  <div v-for="entry in filteredData" :key="entry.id">
    <pre v-text="entry" />
  </div>
</div>

【讨论】:

    猜你喜欢
    • 2020-01-23
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    相关资源
    最近更新 更多