Vue

by Nigel Whatling

HTML

<div id="app">
   <header>
      <!-- desktop -->
      <guitar-filters :data="filterData" />
   </header>

   <!-- mobile -->
   <guitar-filters :data="filterData" />
</div>

CSS

ul {
 margin-left:20px; 
}
ul > li {
  cursor: pointer;
}
ul.filters > li > ul > li.selected::before {
   content: "✔️";
}

Vue

Vue.component('guitar-filters', {

    props: [ 'data' ],

    data: function() {
        return {
            isMobile: false
        }
    },

    mounted: function() {
        var comp = this;
        this.setIsMobile();
        window.addEventListener('resize', function() {
            comp.setIsMobile();
        });
    },

    methods: {
        setIsMobile: function() {
            this.isMobile = (window.innerWidth <= 900) ? true : false;
        }
    },

    template: `
        <ul class="filters" :class="{mobile: isMobile}">

        <li>
            All
        </il>

        <li>
            Series
            <instrument-filters :list="data.seriesFilters"/>
        </li>

        <li>
            Body Shape
            <instrument-filters :list="data.bodyFilters"/>
        </li>

    </ul>
    `

});

Vue.component('instrument-filters', {

    props : [ 'list', ],

    methods: {
        toggle(toggleItem) {
          let itemInList = this.list.find((item) => item.value === toggleItem.value);        
        	itemInList.selected = !itemInList.selected;       
        },
    },

    template: `
    		<ul>
          <li v-for="item in list" :class="{ 'selected' : item.selected }" @click="toggle(item)">{{ item.label }}</li>
        </ul>
    `

});

new Vue({
  el: "#app",
  data: {
    filterData: {
      seriesFilters: [
        { label: 'All', value: 'All', selected: false },
        { label: 'Frontier', value: 'Frontier', selected: false },
        { label: 'Legacy', value: 'Legacy', selected: false },
        { label: 'USA', value: 'USA', selected: false },
      ],
      bodyFilters: [
        { label: 'All', value: 'All', selected: false },
        { label: 'Concert', value: 'Concert', selected: false },
        { label: 'Concertina', value: 'Concertina', selected: false },
        { label: 'Concerto', value: 'Concerto', selected: false },
        { label: 'Orchestra', value: 'Orchestra', selected: false },
      ],
    }
  },
});