Part 2: components - SOLUTION

Step 1

Vue.component('hostel-list-item', {
  template: `
    <div class="card" v-show="hostel.isActive">
      <div class="content">
        <div class="right floated meta">{{ hostel.price.amount }}{{ hostel.price.currency }}</div>
        <div class="header">{{ hostel.name }}</div>
      </div>
      <div class="content">
        <div class="meta">
          {{ hostel.location }}
          <i v-if="hostel.bonus.hasFreeWifi" class="wifi icon"></i>
          <i v-if="hostel.bonus.hasFreeBreakfast" class="coffee icon"></i>
          <i v-if="hostel.bonus.hasTv" class="desktop icon"></i>
          <i v-if="hostel.bonus.hasBar" class="bar icon"></i>
        </div>
        <div class="description">
          {{ hostel.description }}
        </div>
      </div>
      <div v-if="hostel.availability" class="ui orange bottom attached button">
        Book now
      </div>
      <div v-else class="ui bottom attached disabled button">
        Too late!
      </div>
    </div>
  `,
  props: ['hostel']
})
<div id="app" class="ui container">
  <h1 class="ui center aligned header">HostelVue</h1>

  <form class="ui form">
    <div class="field">
      <input type="text" placeholder="filter by name" v-model="userSearch">
    </div>
  </form>
  <br>

  <div class="ui cards">
    <hostel-list-item 
      v-for="hostel in hostelsShown" 
      :hostel="hostel"
    ></hostel-list-item>
  </div>

</div>

Step 2

<div id="app" class="ui container">
  <h1 class="ui center aligned header">HostelVue</h1>

  <form class="ui form">
    <div class="field">
      <input type="text" placeholder="filter by name" v-model="userSearch">
    </div>
  </form>
  <br>

  <div class="ui cards">
    <hostel-list-item 
      v-for="hostelShown in hostelsShown"
      v-if="hostelShown.isActive"
      :hostel="hostelShown"
      :like="likedHostels.indexOf(hostelShown) !== -1"
      v-on:like="likeHostel"
    ></hostel-list-item>
  </div>

</div>
<script>
Vue.component('hostel-list-item', {
  template: `
    <div class="card">
      <div class="content">
        <div class="right floated meta">
          <i v-bind:class="{ red: like }" class="heart icon" @click="$emit('like', hostel)"></i>
        </div>
        <div class="header">{{ hostel.name }}</div>
        </div>
        <div class="content">
          <div class="meta">
            {{ hostel.location }}
            <i v-if="hostel.bonus.hasFreeWifi" class="wifi icon"></i>
            <i v-if="hostel.bonus.hasFreeBreakfast" class="coffee icon"></i>
            <i v-if="hostel.bonus.hasTv" class="desktop icon"></i>
            <i v-if="hostel.bonus.hasBar" class="bar icon"></i>
            <div class="right floated meta">
                {{ hostel.price.amount }}{{ hostel.price.currency }}/night
              </div>
          </div>
          <div class="description">
              {{ hostel.description }}
          </div>
        </div>
        <div v-if="hostel.availability" class="ui orange bottom attached button">
          Book now
        </div>
        <div v-else class="ui bottom attached disabled button">
          Too late!
        </div>
    </div>
  `,
  props: ['hostel', 'like'],
})

  var app = new Vue({
    el: '#app',
    data: {
      userSearch: '',
      likedHostels: [],
      hostels: [ /*... ...*/ ]
    },
    computed: {
      hostelsShown () {
        return this.hostels
          .filter(hostel => hostel.name.toLowerCase().includes(this.userSearch))
      }
    },
    methods: {
      likeHostel (hostel) {
        if (this.likedHostels.indexOf(hostel) === -1) {
          this.likedHostels.push(hostel)
        } else {
          this.likedHostels.splice(this.likedHostels.indexOf(hostel), 1)
        }
      }
    }
  })
  </script>

Step 3

<form class="ui form">
  <div class="inline fields">
    <div class="one wide field">
      <i :class="onlyShowLiked ? 'red' : 'grey'" class="heart icon" @click="toogleLikeFilter" title="Only show liked hostels"></i>
    </div>
    <div class="fifteen wide field">
      <input type="text" placeholder="filter by name" v-model="userSearch">
    </div>
  </div>
</form>
  var app = new Vue({
    el: '#app',
    data: {
      onlyShowLiked: false,
      // ...
    },
    computed: {
      hostelsShown () {
        const likeFilter = (hostel) => {
          if (this.onlyShowLiked) {
            return this.likedHostels.indexOf(hostel) !== -1
          }
          return true
        }

        return this.hostels
          .filter(likeFilter)
          .filter(hostel => hostel.name.toLowerCase().includes(this.userSearch))
      }
    },
    methods: {
      // ...
      toogleLikeFilter () {
        if (this.onlyShowLiked === false) {
          this.onlyShowLiked = true
        } else {
          this.onlyShowLiked = false
        }
      }
    }
  })

results matching ""

    No results matching ""