M
M
Mike2017-07-18 13:57:01
Vue.js
Mike, 2017-07-18 13:57:01

How to do sorting in Vue.js component?

Colleagues, started learning Vue.js. And immediately got stuck. I ask for your help.
How to pass data from component to component and make the simplest sorting, for example, by name.
I am using https://github.com/vuejs-templates/webpack
There are two components.
List of products "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>

I can do sorting / filtering in the component - it's simple.
Perhaps I misunderstood the concept of Vue.js a bit, but in theory, separation into components is necessary.
Tell me where to dig?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
R
RaulDuke, 2017-07-18
@RaulDuke

Good afternoon,
the question smacks of holivar, but I'm not sure about the need for a separate sorting component. I would do something like this:

<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>

A
Anton Anton, 2017-07-18
@Fragster

I would make sorting methods as props, and on click - emit events to the parent component, which sorts as it should. In the component itself with sorting controls, I would not do anything with the data.
Well, if we go deeper (for example, we have a component that contains a sorting component and a list component, and we do not pass the list through props), then we come to vuex. Although in this case it will only complicate it, but with an increase in the amount of data, it no longer exists.

E
Evgeny Kulakov, 2017-07-18
@kulakoff Vue.js

It is possible in different ways, as an option:
1. Sorting
component 2. Sheet
component 3. Sheet component with sorting - in fact there is an aggregator of the first two
. you get something like:
// 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>

I wrote the code by hand, there are definitely errors)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question