Step 1: tạo trang Kiểm tra giỏ hàng CartCheckout

  • Tạo file project-nentang/src/pages/CartCheckout.vue
  • Nội dung file như sau:
<template>
<section>
<div class="container">
<div class="row">
<div class="col">
<h1 class="text-center">Giỏ hàng</h1>
</div>
</div>
<div class="row">
<div class="col">
<table class="table table-borderd table-striped">
<thead>
<th>STT</th>
<th>Hình đại diện</th>
<th>Tên sản phẩm</th>
<th>Giá</th>
<th>Số lượng</th>
<th>Thành tiền</th>
<th>#</th>
</thead>
<tbody>
<tr
v-for="(product, index) in getProductsInCart"
v-bind:key="product.id"
>
<td>{{ index + 1 }}</td>
<td>
<img
:src="product.image"
alt=""
class="product-item-in-cart-img"
/>
</td>
<td>{{ product.name }}</td>
<td class="text-right">{{ product.price }}</td>
<td class="text-right">{{ product.totalBuyed }}</td>
<td class="text-right">
{{ product.price * product.totalBuyed }}
</td>
<td>
<button class="btn btn-danger" @click="remove(product.id)">
<font-awesome-icon :icon="['fas', 'trash']" />&nbsp;Xóa
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-right">Tổng tiền:</td>
<td class="text-right font-weight-bold">
{{ getTotalAmount }}
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</section>
</template>
<script>
// Import helper mapGetters của Vuex để có thể sử dụng getters `getAllProducts` đã khai báo bên KHO chứa (store)
// Import helper mapActions của Vuex để có thể sử dụng actions `removeProduct` đã khai báo bên KHO chứa (store)
import { mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapGetters(['getProductsInCart']),
// Hàm dùng để tính Tổng tiền
getTotalAmount () {
// Duyệt qua tất cả sản phẩm có trong giỏ hàng
// Thành tiền += Giá * Số lượng đã mua
let totalAmount = 0
this.getProductsInCart.forEach(product => {
totalAmount += product.price * product.totalBuyed
})
return totalAmount
}
},
methods: {
...mapActions(['removeProduct']),
// Hàm xóa Sản phẩm khỏi Giỏ hàng
remove (id) {
this.removeProduct(id)
}
}
}
</script>
<style scoped>
.product-item-in-cart-img {
width: 150px;
height: 150px;
object-fit: contain;
}
</style>
<template> <section> <div class="container"> <div class="row"> <div class="col"> <h1 class="text-center">Giỏ hàng</h1> </div> </div> <div class="row"> <div class="col"> <table class="table table-borderd table-striped"> <thead> <th>STT</th> <th>Hình đại diện</th> <th>Tên sản phẩm</th> <th>Giá</th> <th>Số lượng</th> <th>Thành tiền</th> <th>#</th> </thead> <tbody> <tr v-for="(product, index) in getProductsInCart" v-bind:key="product.id" > <td>{{ index + 1 }}</td> <td> <img :src="product.image" alt="" class="product-item-in-cart-img" /> </td> <td>{{ product.name }}</td> <td class="text-right">{{ product.price }}</td> <td class="text-right">{{ product.totalBuyed }}</td> <td class="text-right"> {{ product.price * product.totalBuyed }} </td> <td> <button class="btn btn-danger" @click="remove(product.id)"> <font-awesome-icon :icon="['fas', 'trash']" />&nbsp;Xóa </button> </td> </tr> </tbody> <tfoot> <tr> <td colspan="5" class="text-right">Tổng tiền:</td> <td class="text-right font-weight-bold"> {{ getTotalAmount }} </td> </tr> </tfoot> </table> </div> </div> </div> </section> </template> <script> // Import helper mapGetters của Vuex để có thể sử dụng getters `getAllProducts` đã khai báo bên KHO chứa (store) // Import helper mapActions của Vuex để có thể sử dụng actions `removeProduct` đã khai báo bên KHO chứa (store) import { mapGetters, mapActions } from 'vuex' export default { computed: { ...mapGetters(['getProductsInCart']), // Hàm dùng để tính Tổng tiền getTotalAmount () { // Duyệt qua tất cả sản phẩm có trong giỏ hàng // Thành tiền += Giá * Số lượng đã mua let totalAmount = 0 this.getProductsInCart.forEach(product => { totalAmount += product.price * product.totalBuyed }) return totalAmount } }, methods: { ...mapActions(['removeProduct']), // Hàm xóa Sản phẩm khỏi Giỏ hàng remove (id) { this.removeProduct(id) } } } </script> <style scoped> .product-item-in-cart-img { width: 150px; height: 150px; object-fit: contain; } </style>
<template>
  <section>
    <div class="container">
      <div class="row">
        <div class="col">
          <h1 class="text-center">Giỏ hàng</h1>
        </div>
      </div>

      <div class="row">
        <div class="col">
          <table class="table table-borderd table-striped">
            <thead>
              <th>STT</th>
              <th>Hình đại diện</th>
              <th>Tên sản phẩm</th>
              <th>Giá</th>
              <th>Số lượng</th>
              <th>Thành tiền</th>
              <th>#</th>
            </thead>
            <tbody>
              <tr
                v-for="(product, index) in getProductsInCart"
                v-bind:key="product.id"
              >
                <td>{{ index + 1 }}</td>
                <td>
                  <img
                    :src="product.image"
                    alt=""
                    class="product-item-in-cart-img"
                  />
                </td>
                <td>{{ product.name }}</td>
                <td class="text-right">{{ product.price }}</td>
                <td class="text-right">{{ product.totalBuyed }}</td>
                <td class="text-right">
                  {{ product.price * product.totalBuyed }}
                </td>
                <td>
                  <button class="btn btn-danger" @click="remove(product.id)">
                    <font-awesome-icon :icon="['fas', 'trash']" />&nbsp;Xóa
                  </button>
                </td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="5" class="text-right">Tổng tiền:</td>
                <td class="text-right font-weight-bold">
                  {{ getTotalAmount }}
                </td>
              </tr>
            </tfoot>
          </table>
        </div>
      </div>
    </div>
  </section>
</template>

<script>
// Import helper mapGetters của Vuex để có thể sử dụng getters `getAllProducts` đã khai báo bên KHO chứa (store)
// Import helper mapActions của Vuex để có thể sử dụng actions `removeProduct` đã khai báo bên KHO chứa (store)
import { mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    ...mapGetters(['getProductsInCart']),

    // Hàm dùng để tính Tổng tiền
    getTotalAmount () {
      // Duyệt qua tất cả sản phẩm có trong giỏ hàng
      // Thành tiền += Giá * Số lượng đã mua
      let totalAmount = 0
      this.getProductsInCart.forEach(product => {
        totalAmount += product.price * product.totalBuyed
      })
      return totalAmount
    }
  },
  methods: {
    ...mapActions(['removeProduct']),

    // Hàm xóa Sản phẩm khỏi Giỏ hàng
    remove (id) {
      this.removeProduct(id)
    }
  }
}
</script>

<style scoped>
.product-item-in-cart-img {
  width: 150px;
  height: 150px;
  object-fit: contain;
}
</style>

Step 2: tạo route Trang Kiểm tra Giỏ hàng /kiem-tra-gio-hang

  • Hiệu chỉnh file project-netashop/src/router/index.js
  • Nội dung file như sau:
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Chúng ta sử dụng thuộc tính `meta` trong routes để khai báo:
- Ứng với path / -> sẽ sử dụng layout `default`
- Ứng với path /gioi-thieu -> sẽ sử dụng layout `no-sidebar`
- Ứng với path /lien-he -> sẽ sử dụng layout `no-sidebar`
- Ứng với path /kiem-tra-gio-hang -> sẽ sử dụng layout `no-sidebar`
- Ứng với path không tìm thấy 404 -> sẽ sử dụng layout `no-sidebar`
*/
const routes = [
{
path: '/',
name: 'home',
meta: {
layout: 'default'
},
// component: require('@/pages/Home.vue').default
component: () => import('@/pages/Home.vue')
},
{
path: '/gioi-thieu',
name: 'about',
meta: {
layout: 'no-sidebar'
},
component: () => import('@/pages/About.vue')
},
{
path: '/lien-he',
name: 'contact',
meta: {
layout: 'no-sidebar'
},
component: () => import('@/pages/Contact.vue')
},
{
path: '/kiem-tra-gio-hang',
name: 'cartCheckout',
meta: {
layout: 'no-sidebar'
},
component: () => import('@/pages/CartCheckout.vue')
},
{
path: '*',
name: '404',
meta: {
layout: 'no-sidebar'
},
component: () => import('@/pages/404.vue')
}
]
// Để đường dẫn Path đẹp hơn và thân thiện với người dùng và SEO
// Chúng ta sử dụng History mode thay vì HashTag mode (dấu #)
const router = new Router({
mode: 'history',
routes: routes
})
export default router
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) /* Chúng ta sử dụng thuộc tính `meta` trong routes để khai báo: - Ứng với path / -> sẽ sử dụng layout `default` - Ứng với path /gioi-thieu -> sẽ sử dụng layout `no-sidebar` - Ứng với path /lien-he -> sẽ sử dụng layout `no-sidebar` - Ứng với path /kiem-tra-gio-hang -> sẽ sử dụng layout `no-sidebar` - Ứng với path không tìm thấy 404 -> sẽ sử dụng layout `no-sidebar` */ const routes = [ { path: '/', name: 'home', meta: { layout: 'default' }, // component: require('@/pages/Home.vue').default component: () => import('@/pages/Home.vue') }, { path: '/gioi-thieu', name: 'about', meta: { layout: 'no-sidebar' }, component: () => import('@/pages/About.vue') }, { path: '/lien-he', name: 'contact', meta: { layout: 'no-sidebar' }, component: () => import('@/pages/Contact.vue') }, { path: '/kiem-tra-gio-hang', name: 'cartCheckout', meta: { layout: 'no-sidebar' }, component: () => import('@/pages/CartCheckout.vue') }, { path: '*', name: '404', meta: { layout: 'no-sidebar' }, component: () => import('@/pages/404.vue') } ] // Để đường dẫn Path đẹp hơn và thân thiện với người dùng và SEO // Chúng ta sử dụng History mode thay vì HashTag mode (dấu #) const router = new Router({ mode: 'history', routes: routes }) export default router
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

/* Chúng ta sử dụng thuộc tính `meta` trong routes để khai báo:
- Ứng với path /                  -> sẽ sử dụng layout `default`
- Ứng với path /gioi-thieu        -> sẽ sử dụng layout `no-sidebar`
- Ứng với path /lien-he           -> sẽ sử dụng layout `no-sidebar`
- Ứng với path /kiem-tra-gio-hang -> sẽ sử dụng layout `no-sidebar`
- Ứng với path không tìm thấy 404 -> sẽ sử dụng layout `no-sidebar`
*/
const routes = [
  {
    path: '/',
    name: 'home',
    meta: {
      layout: 'default'
    },
    // component: require('@/pages/Home.vue').default
    component: () => import('@/pages/Home.vue')
  },
  {
    path: '/gioi-thieu',
    name: 'about',
    meta: {
      layout: 'no-sidebar'
    },
    component: () => import('@/pages/About.vue')
  },
  {
    path: '/lien-he',
    name: 'contact',
    meta: {
      layout: 'no-sidebar'
    },
    component: () => import('@/pages/Contact.vue')
  },
  {
    path: '/kiem-tra-gio-hang',
    name: 'cartCheckout',
    meta: {
      layout: 'no-sidebar'
    },
    component: () => import('@/pages/CartCheckout.vue')
  },
  {
    path: '*',
    name: '404',
    meta: {
      layout: 'no-sidebar'
    },
    component: () => import('@/pages/404.vue')
  }
]

// Để đường dẫn Path đẹp hơn và thân thiện với người dùng và SEO
// Chúng ta sử dụng History mode thay vì HashTag mode (dấu #)
const router = new Router({
  mode: 'history',
  routes: routes
})

export default router