admin管理员组

文章数量:1394217

I have this search input:

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

And this "output" area:

<my-p
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"
/>

i imort data from json file and this is the data

[
    {"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"}
]

The idea is that the user searches a city or country or any data and the output should show only the cards he is searching for.

This is the vue js code:

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

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

But my function only accepts one variable. What should I do?

I have this search input:

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

And this "output" area:

<my-p
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"
/>

i imort data from json file and this is the data

[
    {"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"}
]

The idea is that the user searches a city or country or any data and the output should show only the cards he is searching for.

This is the vue js code:

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

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

But my function only accepts one variable. What should I do?

Share Improve this question asked Dec 25, 2021 at 12:29 Khaled AltarhoniKhaled Altarhoni 371 silver badge7 bronze badges 2
  • You either give control to the user and allow them to select the searched column or you search in all columns. – tao Commented Dec 25, 2021 at 12:36
  • Btw, because you use Options API, your question is more Vue2 specific than Vue3 specific, even though this syntax also works in Vue 3. – tao Commented Dec 25, 2021 at 13:25
Add a ment  | 

1 Answer 1

Reset to default 6

Search all columns:

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

See it working:

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"}
]
  }),
  puted: {
    filteredData() {
      return this.allData
        .filter(
          (entry) => this.allData.length
            ? Object.keys(this.allData[0])
                .some(key => ('' + entry[key]).toLowerCase().includes(this.search.toLowerCase()))
            : true
        );
    }
  }
})
<script src="https://cdn.jsdelivr/npm/[email protected]"></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>

Search specific columns:

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

See it working:

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"}
]
  }),
  puted: {
    filteredData() {
      return this.allData
        .filter(
          ({ country, city }) => [country, city]
            .some(val => val.toLowerCase().includes(this.search))
        );
      }
  }
})
<script src="https://cdn.jsdelivr/npm/[email protected]"></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>


First one takes all keys from first entry (if you have any data) casts all values to string (so it can run .toLowerCase() on it) and checks if this.search is included in the value held in that field, for each entry.

Second one is less generic, therefore more exact. You probably want to use it when you know exactly in what fields you want to search, to prevent false positives.


Another option is to give the user a dropdown to select the column they want to filter by.

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"}
]
  }),
  puted: {
    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/npm/[email protected]"></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>

本文标签: javascriptFilter search with computed in vuejs 3Stack Overflow