Home > Mobile >  Vue.js 3 and search
Vue.js 3 and search

Time:11-03

I have a data coming from API. It is an array of "houses".

Code looks like this:

<template>
    <div class="search__sort">
        <input v-model="search" placeholder="Search for a house">
        <button class="sort__button">Price</button>
        <button class="sort__button">Size</button>
    </div>    
    <div v-for="house in houses" :key="house.id" class="house">
        <router-link :to="{ name: 'HouseDetails', params: { id: house.id}}" >
            <h2>ID = {{ house }}</h2>
            <h3> {{ house.location.street}} </h3>
            <img :src="house.image" />
                
        </router-link>
        <button v-if="house.madeByMe" class="delete" @click="deleteHouse(house.id)">Delete</button>
    </div>
   
</template>

<script>
import axios from 'axios'


export default {
    name: 'Houses',
 

    data(){
        return {
            houses: [],
        }
    },
    
    created() {
        this.getHouses();
    },

    methods: {

      

        getHouses(){
            // GET request using axios with set headers
            const headers = { "CENSORED": "CENSORED" };
            axios.get('myAPI', { headers })
            .then(response => this.houses = response.data);
        },

        deleteHouse(id) {
            
            const headers = { "CENSORED": "CENSORED" };
            axios.delete('myAPI'   id, { headers })
            .then(response => {
                console.log(response);
            })
            .catch(function (error) {
                console.log(error.response);
            });
                        
        },
    },
   


}
</script>

I somehow need to implement the filter by text input, so that for example, if user types a city name it will show all of those houses or a street name to filter that by street.

Any suggestions how I can do that with code that I already have?

CodePudding user response:

You can use computed property:

new Vue({
  el: '#demo',
  data() {
    return {
      search: '',
      houses: [{ "id": 2, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "assas", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false }, { "id": 3, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "adb", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false },{ "id": 4, "image": "myAPI/house1.jpg", "price": 123, "rooms": { "bedrooms": 1, "bathrooms": 1 }, "size": 500, "description": "oui", "location": { "street": "street 20", "city": "bbb", "zip": "asasdd" }, "createdAt": "2020-05-07", "constructionYear": 2000, "hasGarage": false, "madeByMe": false }],
    }
  },
  computed: {
    filteredHouses(){
      return this.houses.filter(h => h.location.city.toLowerCase().includes(this.search.toLowerCase()))
    }
  }
})

Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
    <div class="search__sort">
        <input v-model="search" placeholder="Search for a house">
        <button class="sort__button">Price</button>
        <button class="sort__button">Size</button>
    </div>    
    <div v-for="house in filteredHouses" :key="house.id" class="house">
            <h3> {{ house.location.city}} </h3>
            <img :src="house.image" />
   
    </div>
      
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

  1. You will want to distinguish the difference between houses and displayedHouses such that, displayedHouses is your filtered array.

  2. <h2>ID = {{ house }}</h2> is not going to play well with your testing

  3. displayedHouses will be a computed looking something like:

computed:
{
 /**
  * @return {array} List of displayed houses from search input
  */
 displayedHouses()
 {
  if (!this.houses || !this.houses.length)
  {
    return []
  }
  if (!this.search)
  {
    return this.houses
  }
  return this.houses.filter( (house) =>
  {
    return house.city.includes(this.search) || house.state.includes(this.search) // || whatever else you want
  })
 }
},
  • Related