Добавим в компонент два свойства. Вычисляемое - массив уникальных значений типов элементов, и обычное - массив выбранных пользователем типов:
data: () => ({
selectedTypes: [],
...
}),
computed: {
types() {
return [...new Set(this.items.map(n => n.type))];
},
...
},
На основе первого массива создадим чекбоксы, и свяжем с ними второй массив:
<template v-for="n in types">
<input type="checkbox" :value="n" v-model="selectedTypes" :id="n">
<label :for="n">{{ n }}</label>
</template>
Также добавим ещё одно вычисляемое свойство - массив элементов, которые надо показывать (тип которых содержится в массиве выбранных типов):
computed: {
filteredItems() {
const types = this.selectedTypes;
return this.items.filter(n => types.includes(n.type));
},
...
},
Ну и покажем их:
<figure v-for="n in filteredItems">
<img :src="n.src" alt="">
</figure>
https://jsfiddle.net/dzkscv83/
UPD. Вынесено из комментариев:
Сделал немного иначе, работает, но использовал два шаблона, вместо одного
https://jsfiddle.net/madeas/s47gqbaz/5/
Не могу с таким вариантом согласиться.
Два корневых экземпляра vue, вложенные один в другой - никогда так не делайте, для этого есть компоненты.
Опять три раза повторяется css для скрытых item'ов - плохо. Скрываете item'ы основываясь на состоянии чекбоксов вместо того, чтобы смотреть на данные - плохо. Лучше сделать класс, который будет назначаться кому надо. А кого надо будем определять с помощью вычисляемого свойства - массив имён типов, у которых
checked === false
.
Если все элементы, с помощью которых вы управляете видимостью item'ов, являются чекбоксами - нет необходимости назначать тип input'а динамически, и соответственно, хранить его.
https://jsfiddle.net/rkh3wpyc/