Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added ShopVue/img/default.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions ShopVue/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="styles/main.css">
</head>

<body>
<div id="app">
<div class="header">
<div class="name">
<h1>{{title}}</h1>
</div>
<div class="cart">
<table class="search">
<tr>
<td class="search_line">
<input type="text" v-model="search_info">
</td>
<td class="search_btn">
<button class="find" @click="filterGoods()">Search</button>
</td>
</tr>
</table>
<button class="btn-cart" @click="isVisibleCart = !isVisibleCart">Корзина</button>
<div class="user_cart" :class="{hide : !isVisibleCart}" >
<div class="basket_item" v-for="item in basket" :key="item.id_product">
<span><b>{{item.product_name}}</b></span>
<span>x ({{item.quantity}}) </span>
<span> <i>{{item.price}}</i> P </span>
<span><button @click="deleteProduct(item.product_name)"> x </button></span>
<hr>
</div>
</div>
</div>
</div>
<div class="main">
<div class="products">
<div class="no_products" :class="{hide: !isNoProducts}">
<p>Нет данных</p>
</div>
<div class="product-item" :class="product.class" v-for="product in products" :key="product.id_product">
<img src="img/default.jpg" alt="">
<h3>{{product.product_name}}</h3>
<p>price - ${{product.price}}P</p>
<button class="by-btn" id="${this.id}" @click="addProduct($event)">Добавить в корзину</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="js/main.js"></script>
</body>

</html>
139 changes: 139 additions & 0 deletions ShopVue/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
const API = 'https://raw.githubusercontent.com/GeekBrainsTutorial/online-store-api/master/responses/';

const app = new Vue({

el: '#app',

data: {

title: 'Интернет магазин',
products: [],
basket: [],
catalogFile: 'catalogData.json',
basketFile: 'getBasket.json',
search_info: '',
isVisibleCart: false,
isNoProducts: false,
basket_amount: 0,
countGoods: 0,

},

methods: {

getRequest(jsonFile) {

return new Promise((resolve, reject) => {

var xhr = new XMLHttpRequest();
xhr.open('GET', `${API}${jsonFile}`, true);

xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let response = JSON.parse(xhr.responseText);
resolve(response);
} else {
reject('Error');
}
}
}

xhr.send();

});

},
Comment on lines +24 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

у нас же был прекрасный метод с fetch, зачем усложнять?


filterGoods() {
regExp = new RegExp(this.search_info, 'igm');
console.log(regExp);
for ( let product of this.products) {
if ( !regExp.test(product.product_name)) {
product.class = 'hide';
} else {
product.class = 'visible';
}
}
},

addProduct(event) {
let productToAdd = event.target.parentElement.children[1].innerHTML;
for (let product of this.products) {
if ( product.product_name === productToAdd) {
this.addToBasket(product);
break;
}
}

},

addToBasket(product) {
let isAdded = false;
for (item of this.basket) {
if (item.product_name === product.product_name) {
item.quantity += 1;
isAdded = true;
// Чтобы происходило обновление при изменении basket
this.basket.push(0);
this.basket.pop();
Comment on lines +78 to +79
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

костыль-костыльный =( Если и идти такой дорогой то тут больше Vue.set поможет но в целом реализация у нас итак уже есть + повторил про нее на уроке.

break;
}
}

if ( !isAdded ) {
product['quantity'] = 1;
// basket обновился => доп. изменения не нужны
this.basket.push(product);
}

},

deleteProduct(product_name) {
console.log(product_name);
for (let i=0; i < this.basket.length; i++) {
if ( this.basket[i].product_name === product_name) {
if ( this.basket[i].quantity >= 2) {
this.basket[i].quantity--;
} else {
this.basket.splice(i,1);
}
// Чтобы происходило обновление при изменении basket
this.basket.push(0);
this.basket.pop();
break;
}
}


console.log(this.basket);
}

},
created() {
this.getRequest(this.catalogFile)
.then(data => {
console.log(data);
for (let item of data) {
console.log(typeof(item));
item['class'] = 'visible';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это можно вынести в шаблон, ибо хранить данные о стилях в списке товаров, которые вообще не должны содержать данные о представлении.

this.products.push(item);
}
if (this.products.length === 0) {
this.isNoProducts = true;
}
console.log(this.products);
});

this.getRequest(this.basketFile)
.then(data => {
console.log(data);
this.countGoods = data.countGoods;
this.basket_amount = data.amount;
this.basket = data.contents;
console.log(this.basket);

});
},

});
142 changes: 142 additions & 0 deletions ShopVue/styles/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
* {
margin: 0;
padding: 0;
}

.header {
min-height: 60px;
background-color: aqua;
position: relative;
}

h1 {
padding-top: 10px;
}

.cart {

position: absolute;
top: 10px;
right: 20px;

}

.search {
float: left;
margin-top: 3px;
margin-right: 20px;
border-collapse: collapse;
}

.search_line {
border-bottom: 2px solid black;
padding: 2px;
}

.search_line input {
padding: 5px;
}

.search_btn {
border-bottom: 2px solid black;
}

.search_btn .find {
display: block;
height: 30px;
}

.btn-cart {
display: block;
right: 12px;
top: 10px;
width: 90px;
height: 40px;

}

.main-btn {
text-align: center;
display: block;
width: 150px;
height: 50px;
margin: 0 auto;
}

.products {
min-height: 100px;
border: 1px solid black;
}

.product-item {
margin: 15px 15px;
background-color: azure;
border: 1px solid black;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
}

.product-item img {
display: block;
max-height: 100px;
margin: 10px 10px;
float: left;
border-radius: 10%;
}

.product-item h3 {
text-align: center;
margin-top: 10px;
font-style: oblique;
}

.product-item p {
text-align: center;
margin-top: 10px;
color: royalblue;
font-style: italic;
}

.product-item .by-btn {
display: block;
text-align: center;
height: 40px;
width: 150px;
margin: 10px auto;
}

.user_cart {
position: absolute;
background-color: lightgrey;
display: block;
min-height: 50px;
width: 200px;
right: 5px;
top: 50px
}

.user_cart:before {
content: '';
width: 0;
position: absolute;
height: 0;
border-right: 10px solid transparent;
border-left: 10px solid transparent;
border-bottom: 10px solid lightgrey;
top: -10px;
right: 35px;
}

.basket_item {
width: inherit;
}

.hide {
display: none;
}

.no_products p {
display: block;
margin: 0 auto;
font-size: 20px;
text-align: center;
}