Vue

by lavezzi

HTML

<div id="app">
  <div style="width: 25%; display: inline-block;" v-for="product in products">
	  <product_item
      @weight-change="weightChange"
	    :id="product.id" 
	    :title="product.title" 
	    :composition="product.composition" 
	    :price="product.price" 
	    :src="product.src"
	   />
	</div>
</div>

CSS

.products-item {
  margin-bottom: 2rem;
  transition: all 0.15s ease-in-out;
}
.products-item:hover {
  transform: translateY(-2%);
  box-shadow: 0 0 1rem #eee;
  border-radius: .5rem;
}
.products-item img {
  box-shadow: 0 0.5rem 0.5rem -0.5rem #ddd;
  border-radius: .5rem;
}
.products-item .products-item-body {
  border-radius: 0 0 .5rem .5rem;
  padding: 2.5rem 1.5rem 1.5rem;
  background-color: #f9f9f9;
  margin-top: -1rem;
}
.products-item .products-item-body h5:first-of-type {
  margin-bottom: -.1rem;
  font-weight: bold;
}
.products-item .products-item-body small {
  color: #989898;
}
.products-item .products-item-body .products-item-body-range {
  margin: 2rem 0 .5rem;
}
.products-item .products-item-body .products-item-body-range .col small {
  border-radius: 1rem 1rem 1rem 0;
  background-color: #e31e24;
  left: calc(15px + .8rem);
  padding: .1rem .6rem;
  white-space: nowrap;
  position: absolute;
  font-weight: bold;
  top: -1.5rem;
  color: #fff;
  z-index: 1;
}
.products-item .products-item-body .products-item-body-range input[type=range]::-webkit-slider-thumb {
  background: #e31e24;
}
.products-item .products-item-body .products-item-body-range input[type=range]:focus::-webkit-slider-thumb {
  box-shadow: 0 0 0 1px white, 0 0 0 3px rgba(227, 30, 36, 0.15);
}
.products-item .products-item-body .products-item-body-qty {
  display: inline-block;
  border: 2px solid #dee2e6;
  padding: 0 0.4rem 0.075rem;
  background: transparent;
  margin-right: 0.3rem;
  border-radius: 2rem;
}
.products-item .products-item-body .products-item-body-qty input {
  vertical-align: baseline;
  text-align: center;
  font-weight: 700;
  background: none;
  border: unset;
  width: 20px;
}
.products-item .products-item-body .products-item-body-qty input:focus {
  box-shadow: 0;
}
.products-item .products-item-body .products-item-body-qty a {
  text-decoration: none;
  cursor: pointer;
  color: #dee2e6;
}
.products-item .products-item-body .products-item-body-qty a:hover,...

Vue

Vue.component('product_item', {
  props: ['id', 'title', 'composition', 'price', 'src'],
	data() {
    return {
      value: 1,
      x: 33,
      qty: 1
    }
	},
	methods: {
    move(event) {
      let rect = event.target.getBoundingClientRect();
      this.x = event.pageX - rect.left + 28;
    },
    plus() {
      return this.qty > 0 && this.qty < 99 ? this.qty++ : '';
    },
    minus() {
      return this.qty != 1 ? this.qty-- : '';
    },
    getPrice() {
      alert(this.price);
    },
    rangeChange(e, id) {
    	this.$emit('weight-change', { id, weight: Number(e.target.value) });
    },
  },
  computed: {
    total() {
      return this.value
    }
  },
  template: `<div class="products-item">
		<a href="#"><img :src="src" :alt="title" class="img-fluid" style="width: 100%;"></a>
		<div class="products-item-body">
			<h5><a href="#" class="text-body">{{ title }}</a></h5>
			<small>{{ composition }}</small>
			<div class="products-item-body-range">
				<div class="row">
					<div class="col">
						<label for="range" class="mb-0">Вес продукта</label>
					</div>
					<div class="col">
						<input @change="rangeChange($event, id)" type="range" class="custom-range" min="1" max="5" step="0.5" id="range" v-model="value" @click="move">
						<div>{{ total }} кг</div>
					</div>
				</div>
			</div>
			<div class="row align-items-center">
				<div class="col">
					<h5 class="mb-0" @click="getPrice">{{ price }}</h5>
				</div>
				<div class="col text-right">
					<div class="products-item-body-qty">
						<a href="javascript:void(0);" class="far fa-chevron-left" @click="minus"><</a>
						<input type="text" maxlength="2" :value="qty" @input="qty = $event.target.value">
						<a href="javascript:void(0);" class="far fa-chevron-right" @click="plus">></a>
					</div>
					<a href="javascript:void(0);" class="addToCart" data-toggle="tooltip" data-placement="top" title="В корзину"><i class="far...