ショッピングカートに追加する


この記事では、我々のアプリケーションのショッピングカートフロントエンドを構築する予定です.私たちはより速く熱いモジュール再ロードを持っているVue Viteを使用しています.
チェックしてくださいbackend part built in Nodejs , 我々がすでに発表したもの.
VITE用のアプリケーションディレクトリを作成する必要があります.クリエイトアvue-cart デスクトップのディレクトリと、このコマンドを実行してセットアップVITEを実行します
cd desktop
mkdir vue-cart && cd vue-cart
npm init vite-app vue-cart
VITEアプリケーションを初期化した後、端末でこれを実行します.
cd vue-cart
npm install
code . && npm run dev
The code . コマンドはVisual Studioコードでプロジェクトを開きます.
我々は、アプリケーションのユーザーインターフェイスを設定して続行されます.すべてのUIコンポーネントをWrapPixel's UI Kit .
WrapPixelは素晴らしいUIテンプレートを得ることができるオンラインテンプレートストアですvue templates .
つのコンポーネントを作りましょうproduct.vue and chart.vue . The product.Vue すべての当社の製品とcart.vue ウィルはカート内のすべてのアイテムを一覧表示します.
我々は、我々のアプリケーションにCDNを加えることによってブートストラップを構成する必要がありますindex.html ファイル.
私たちはブートストラップのCSS CDNに興味を持っていますので、公式ブートストラップのCDNに頭をつけ、CSSリンクをコピーしてインデックスに追加します.HTMLファイル
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite app</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
    integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
</head>
<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>
これでコンポーネントを設定できます.私たちは私たちのアプリケーションのルートVuejsファイルとセットアップルーティングを作成することから始めます.
Vue 3ルータを起動してインストールします.
 npm i --save [email protected]
これをインストールした後、私たちのアプリケーションのセットアップのルートをする必要があります.我々は、我々のカートアイテムを示す基本的なルートを持ちます.
クリエイトアrouter.js ファイルの内部src ディレクトリと次のコードを追加します
import {
    createWebHistory,
    createRouter
} from "vue-router";
import Home from "./components/HelloWorld.vue";
import Product from './components/product.vue'
import Cart from './components/cart.vue'
const history = createWebHistory();
const routes = [{
    path: "/",
    component: Product
}, {
    path: "/cart",
    component: Cart
}, ];
const router = createRouter({
    history,
    routes
});
export default router;
ここで、我々が基本的にしていることは、ルートとして我々のカートと製品構成要素を登録することです.
我々は、我々のメインに我々のルートを登録しなければなりません.jsファイル
import {
    createApp
} from 'vue'
import App from './App.vue'
import './index.css'
import router from "./router";

createApp(App).use(router).mount('#app')
これを行うと、我々は変更する必要がありますApp.vue これをrootコンポーネントでレンダリングします.
<template>
  <nav class="navbar navbar-expand-lg navbar-light bg-info">
    <div class="container">
      <router-link to="/" class="navbar-brand">Vue Cart </router-link>
      <button
        class="navbar-toggler"
        type="button"
        data-toggle="collapse"
        data-target="#navbarNav"
        aria-controls="navbarNav"
        aria-expanded="false"
        aria-label="Toggle navigation"
      >
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse justify-content-end" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item active">
            <router-link to="/" class="nav-link">Home </router-link>
          </li>
          <li class="nav-item">
            <router-link to="/cart" class="nav-link">Cart </router-link>
          </li>
        </ul>
      </div>
    </div>
  </nav>
  <router-view />
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
  name: "App",
  components: {
    HelloWorld,
  },
};
</script>
我々は現在、当社の製品カードを設定することができますし、我々のバックエンドAPIにHTTPリクエストを確認します.
私たちのホームページのシンプルなユーザーインターフェイスを作成できます.これを加えるproduct.vue ファイル
<template>
  <main>
    <section>
      <div
        class="banner-innerpage"
        style="
          background-image: url(https://images.pexels.com/photos/1005638/pexels-photo-1005638.jpeg?cs=srgb&dl=pexels-oleg-magni-1005638.jpg&fm=jpg);
        "
      >
        <div class="container">
          <!-- Row  -->
          <div class="row justify-content-center">
            <!-- Column -->
            <div
              class="col-md-6 align-self-center text-center"
              data-aos="fade-down"
              data-aos-duration="1200"
            >
              <h1 class="title">Shop listing</h1>
              <h6 class="subtitle op-8">
                We are small team of creative people working together
              </h6>
            </div>
            <!-- Column -->
          </div>
        </div>
      </div>
    </section>
    <section>
      <div class="spacer">
        <div class="container">
          <div class="row mt-5">
            <div class="col-lg-9">
              <div class="row shop-listing">
                <div class="col-lg-6">
                  <div class="card shop-hover border-0">
                    <img
                      src="https://images.pexels.com/photos/1005638/pexels-photo-1005638.jpeg?cs=srgb&dl=pexels-oleg-magni-1005638.jpg&fm=jpg"
                      alt="wrapkit"
                      class="img-fluid"
                    />
                    <div class="card-img-overlay align-items-center">
                      <button class="btn btn-md btn-info">
                        Add to cart
                      </button>
                    </div>
                  </div>
                  <div class="card border-0">
                    <h6><a href="#" class="link">Mens Wear </a></h6>
                    <h6 class="subtitle">by Wisdom</h6>
                    <h5 class="font-medium m-b-30">
                      $195 / <del class="text-muted line-through">$225</del>
                    </h5>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </main>
</template>
<style>
.banner-innerpage {
  padding: 150px 0 100px;
  background-size: cover;
  background-position: center center;
}
.banner-innerpage .title {
  color: #ffffff;
  text-transform: uppercase;
  font-weight: 700;
  font-size: 40px;
  line-height: 40px;
}
.banner-innerpage .subtitle {
  color: #ffffff;
}
.shop-listing .shop-hover {
  position: relative;
}
.shop-listing .shop-hover .card-img-overlay {
  display: none;
  background: rgba(255, 255, 255, 0.5);
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
}
.shop-listing .shop-hover:hover .card-img-overlay {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}
.shop-listing .shop-hover .label {
  padding: 5px 10px;
  position: absolute;
  top: 10px;
  right: 10px;
}
/*******************
shop table
*******************/
.shop-table td {
  padding: 30px 0;
}
</style>
これは、我々のアプリケーションのためのシンプルなユーザーインターフェイスを作成します.次に、エンドポイントの消費を開始する必要があります.以前のチュートリアルで作成したバックエンドAPIを起動し、バックエンドにリクエストを作成するためにJavaScriptを使用します.
次のスクリプトを<script> 製品コンポーネントのセクション:
<script>
export default {
  data() {
    return {
      products: [],
    };
  },
  created() {
    this.getProducts();
  },
  methods: {
    async getProducts() {
      const res = await fetch("http://localhost:4000/product");
      const data = await res.json();
      this.products = new Proxy(data.data, {});
      console.log(this.products);
    },
  },
};
</script>
これは私たちのバックエンドAPIへの要求をし、すべての製品のリストを取得し、製品を
データインスタンス.
我々は今、Vuejsを使用して当社の製品をループすることができますv-for これに製品カードを保持するカラムを変更することによるディレクティブ
     <div
          class="col-lg-4"
          v-for="product in products"
          :key="product._id"
          >
          <div class="card shop-hover border-0">
          <img
          :src="'http://localhost:4000/' + product.image"
          alt="wrapkit"
          class="img-fluid"
          />
            <div class="card-img-overlay align-items-center">
             <button class="btn btn-md btn-info">
                Add to Cart
             </button>
            </div>
          </div>
          <div class="card border-0">
             <h6>
                <a href="#" class="link">{{ product.name }} </a>
             </h6>
             <h6 class="subtitle">by Wisdom</h6>
             <h5 class="font-medium m-b-30">
                $195 / <del class="text-muted line-through">$225</del>
             </h5>
          </div>
     </div>
これは、当社のデータベースに格納されているすべての製品を一覧表示されます

今すぐ追加add to cart 機能.私たちは、製品IDとデフォルト量を1として、それを我々のバックエンドに送る方法をつくります.
定義するaddToCart メソッド:
 async addToCart(id, quantity) {
      try {
        const response = await fetch("http://localhost:4000/cart", {
          method: "POST",
          body: JSON.stringify({
            productId: id,
            quantity: quantity,
          }),
          headers: {
            "Content-type": "application/json; charset=UTF-8",
          },
        });
        let data = await response.json();
        alert("Item added to cart");
        console.log(data);
      } catch (err) {
        alert("Something went wrong");
        console.log(err);
      }
    },
このあと、ボタンをクリックしてメソッドをトリガーする必要があります.
 <button
    class="btn btn-md btn-info"
    @click="addToCart(product._id, 1)"
    >
      Add to Cart
 </button>
ここでは、productIdとデフォルトの量を1とします.
カートのアイテムの表示、カートのttemsの増分とカートの空飛ぶことの現在の作業を開始することができます.
ヘッドオーバーcart.vue コンポーネントとユーザーインターフェイスの構築
<template>
  <main>
    <section>
      <div
        class="banner-innerpage"
        style="
          background-image: url(https://images.pexels.com/photos/1005638/pexels-photo-1005638.jpeg?cs=srgb&dl=pexels-oleg-magni-1005638.jpg&fm=jpg);
        "
      >
        <div class="container">
          <!-- Row  -->
          <div class="row justify-content-center">
            <!-- Column -->
            <div
              class="col-md-6 align-self-center text-center"
              data-aos="fade-down"
              data-aos-duration="1200"
            >
              <h1 class="title">Cart</h1>
              <h6 class="subtitle op-8">
                We are small team of creative people working together.
              </h6>
            </div>
            <!-- Column -->
          </div>
        </div>
      </div>
    </section>
    <section>
      <div class="spacer">
        <div class="container">
          <div class="row mt-5">
            <div class="col-lg-9">
              <div class="row shop-listing">
                <table class="table shop-table">
                  <tr>
                    <th class="b-0">Image</th>
                    <th class="b-0">Name</th>
                    <th class="b-0">Price</th>
                    <th class="b-0">Quantity</th>
                    <th class="b-0 text-right">Total Price</th>
                  </tr>
                  <tr>
                    <td>
                      <img
                        src="../assets/images/innerpage/shop/1.jpg"
                        width="200"
                        alt="wrapkit"
                      />
                    </td>
                    <td>
                      Mens Wear
                    </td>
                    <td>
                      $3000
                    </td>
                    <td>
                      <button class="btn btn-primary btn-sm">+</button> 3
                      <button class="btn btn-primary btn-sm">
                        -
                      </button>
                    </td>
                    <td class="text-right">
                      <h5 class="font-medium m-b-30">
                        $195
                      </h5>
                    </td>
                  </tr>
                  <tr>
                    <td colspan="4" align="right">Subtotal :$1000</td>
<td colspan="4" align="right">
                      <button class="btn btn-danger">Empty Cart</button>
                    </td>
                  </tr>

                </table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </main>
</template>
これは、このシンプルなユーザインタフェースを提供します.

すべてのアイテムをバックエンドから取得する方法を作成することで、すべてのカート項目の取得を実装しましょう.
<script>
export default {
  data() {
    return {
      carts: {},
    };
  },
  methods: {
    async getCartItems() {
      try {
        const res = await fetch("http://localhost:4000/cart");
        const data = await res.json();
        this.carts = new Proxy(data.data, {});
        console.log(this.carts);
      } catch (err) {
        console.log(err);
      }
    },
  },
  created() {
    this.getCartItems();
  },
};
</script>
これをテーブルに変更することで、カートのアイテムをループすることができます.
              <table class="table shop-table">
                      <tr>
                        <th class="b-0">Name</th>
                        <th class="b-0">Price</th>
                        <th class="b-0">Quantity</th>
                        <th class="b-0 text-right">Total Price</th>
                      </tr>
                      <tr v-for="(item, id) in carts.items" :key="id">
                        <td>{{ item.productId.name }}</td>
                        <td>{{ item.productId.price }}</td>
                        <td>
                          <button
                            class="btn btn-primary btn-sm"
                            @click="increaseQty(item.productId._id)"
                          >+</button>
                          {{ item.quantity }}
                          <button
                            class="btn btn-primary btn-sm"
                          >-</button>
                        </td>
                        <td class="text-right">
                          <h5 class="font-medium m-b-30">{{ item.total }}</h5>
                        </td>
                      </tr>
                      <tr>
                        <td colspan="3" align="right">Subtotal :{{ carts.subTotal }}</td>
                        <td colspan="4" align="right">
                          <button class="btn btn-danger">Empty Cart</button>
                        </td>
                      </tr>
                    </table>
これでインクリメントするメソッドを追加することでカートアイテム量の増分を実装できます.
    async increaseQty(id) {
      try {
        const res = await fetch("http://localhost:4000/cart", {
          method: "POST",
          body: JSON.stringify({
            productId: id,
            quantity: 1,
          }),
          headers: {
            "Content-type": "application/json; charset=UTF-8",
          },
        });
        this.getCartItems();
        alert("Item Increamented");
      } catch (err) {
        console.log(err);
      }
    },
次に、このメソッドを聞いてもクリックを追加します.
<button
   class="btn btn-primary btn-sm"                          
   @click="increaseQty(item.productId._id)"
   >+
</button>
をクリックする+ ボタンは、アイテムの量をインクリメントし、また、価格を更新します.
空のカート機能を実装します.これは我々のカートを空にして、製品リストページに我々をリダイレクトします.メソッドを作成します.
  async emptyCart() {
      try {
        const res = await fetch("http://localhost:4000/cart/empty-cart", {
          method: "DELETE",
        });
        const data = await res.json();
        this.$router.push({
          path: "/",
        });
      } catch (err) {
        console.log(err);
      }
    },
次に、このメソッドを聞いてイベントリスナーを追加します.
<button class="btn btn-danger" @click="emptyCart">Empty cart</button>

運動

  • デクリメント機能の実装
  • カートから製品を削除する
  • これを実行した後、Gitにあなたの仕事をプッシュし、コメントのセクションのリンクを追加します.楽しみましょう😁