ddale
@ddale
Front-end developer

Как сделать сортировку в компоненте Vue.js?

Коллеги, начал изучение Vue.js. И сразу попал в стопор. Прошу вашей помощи.

Как прокинуть данные из компонента в компонент и сделать простейшую сортировку, например по имени.
Использую https://github.com/vuejs-templates/webpack

Есть два компонента.
Список продуктов "ListProducts"
<template lang="jade">
.b-list-products
    .b-list-products__item(v-for="product in products")
        a.b-list-products__link-img(
            href="#"
        )
            h2.b-list-products__category {{ product.category }}
            img.b-list-products__img(
                :src="product.image"
            )
        a.b-list-products__title(
            href="#"
        ) {{ product.title }}
        .b-list-products__price
            b {{ product.price }} руб
            | &nbsp;/&nbsp;
            span(
                v-if="product.gram == true"
            ) гр
            span(
                v-else
            ) шт
        .b-list-products__year-and-country {{ product.year }}, {{ product.country }}
</template>

<script>
export default{
    name: 'list-products',
    prop: ['products', 'title', 'price'],
    data: () => {
        return {
            products: [
                {
                    category: 'Посуда',
                    image: 'http://teadrinkers.org/assets/images/products/417/c2cee981a39099c7fa00c9c7797dfe7afae168fb.jpg',
                    title: 'Заголовок',
                    price: '10',
                    year: '2015',
                    country: 'Китай',
                    gram: false
                },
                {
                    category: 'Посуда',
                    image: 'http://teadrinkers.org/assets/images/products/354/42993ea70df676dfc302af7073b2503f581c2132.jpg',
                    title: 'Чашка глина (1)',
                    price: '500',
                    year: '2017',
                    country: 'Япония',
                    gram: false
                },
                {
                    category: 'Улун',
                    image: 'http://teadrinkers.org/assets/images/products/305/8386f5419680011666732dcf3a385a5c197d3ab9.png',
                    title: 'ГАБА улун полусферической скрутки',
                    price: '20',
                    year: '2002',
                    country: 'Китай',
                    gram: true
                },
                {
                    category: 'Красный чай',
                    image: 'http://teadrinkers.org/assets/images/products/433/34abe5f187227d79e0e8f7bb60711817072066f5.jpg',
                    title: 'Чжэн Хэ Сяо Чжун',
                    price: '22',
                    year: '2013',
                    country: 'Китай',
                    gram: true
                }
            ]
        }
    }
}
</script>


Сортировка "Sorting"
<template lang="jade">
.b-sorting
    .b-sorting__title Сортировать:
    .b-sorting__list
        .b-sorting__item по цене
        .b-sorting__item по названию
        div {{ sharedItems }}
</template>

<script>
import ListProducts from '@/components/ListProducts.vue'
export default{
    name: 'sorting',
    components: {
        ListProducts
    },
    props: ['products', 'title', 'price'],
    data: () => {
        return {
            sharedItems: ListProducts.data
        }
    }
}
</script>


Сортировку/фильтрацию в компоненте я сделать могу - это просто.
Возможно я немного не понял концепцию Vue.js, но по идее разделение на компоненты ведь необходимо.
Подскажите куда копать?
  • Вопрос задан
  • 3231 просмотр
Пригласить эксперта
Ответы на вопрос 3
@RaulDuke
Добрый день,

от вопроса попахивает холиваром, но я не уверен в необходимости отдельного компонента сортировки. Я бы делал что-то такое:

<template>

  <ul>
    <li @click = "currentSorting = 'name'"> byName </li>
    <li @click = "currentSorting = 'price'"> byPrice </li>
  </ul>

  <app-product v-for="product in productsBy" 
    :key="product.id" 
    :product="product">
  </app-product>
</template>

<script>
  import AppProduct from './app-product.vue';

  export default {
    name: 'products-list',
    components: { AppProduct },
    data() {
      return {
        currentSorting: 'name',
        products: [ {id: 'sdfsdfsdf}, {id: '121qwqwe'}, {id: '2oo23o'} ]
      }
    },
    computed: {
      productsBy: function() {
        switch(this.currentSorting) {
          case 'name': return this.products
          case 'price': return this.products
        }
      }
    }
  }
</script>
Ответ написан
Комментировать
Fragster
@Fragster
помогло? отметь решением!
Я бы сделал в качестве props способы сортировки, а по клику - emit события в родительский компонент, который сортирует как надо. В самом компоненте с контролами сортировки я бы ничего с данными не делал.
Ну и если углубляться дальше (например у нас компонент, который содержит компонент сортировки и компонент-список, и список мы не передаем через props), то мы приходим к vuex. Хотя в данном случае он только усложнит, но при увеличении количества данных - уже нет.
Ответ написан
Комментировать
kulakoff
@kulakoff Куратор тега Vue.js
Vue.js developing
Можно по-разному, как вариант:

1. Компонент сортировки
2. Компонент листа
3. Компонент листа с сортировкой - по сути есть агрегатор первых двух

Т.е. получится что-то типа:
// sortable-list.vue
<template>
  <sort v-model="sortType"></sort>
  <list :items="sortedItems"></list>
</template>

<script>
export default {
  props: ['items'],
  data() {
    return {
      sortType: 'byName'
    }
  },
  computed: {
    sortedItems() {
      switch(this.sortType) {
        case 'byName': return  // sort by name
        case 'bySomething': return  // sort by something
      } 
    }
  }
}
</script>


Код от руки писал, ошибки точно есть)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы