简单的购物车案例

vue+bootstrap实现的购物车案例

效果图

 

功能

  • 添加、减少或直接输入商品数量
  • 移除商品
  • 全选和非全选
  • 计算总价格
  • 清空购物车
  • 人名和商品数量的排序

 

简单的代码实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/font-awesome/5.13.0/css/all.min.css">
  <style>
    #app {
      padding: 20px;
    }
  </style>
  <title>Document</title>
</head>

<body>
  <div id="app">
    <div>
      <h3>Cart</h3>
      <table class="table table-striped table-hover table-bordered text-center" style="font-size: 16px;">
        <thead>
          <tr>
            <th scope="col"></th>
            <th scope="col" @click="sortName" :style="currentIndex === 1 ? {color: 'red'} : ''">Name<i
                class="fa fa-filter"></i></th>
            <th scope="col" @click="sortQuality" :style="currentIndex === 2 ? {color: 'red'} : ''">Quality<i
                class="fa fa-filter"></i></th>
            <th scope="col"><i>(standard)</i>Price<i>(USD)</i></th>
            <th scope="col">Sub-total(USD)</th>
            <th scope="col">Add/Sub</th>
            <th scope="col">Operation</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in list">
            <td><input type="checkbox" :checked="item.checked" @change="handelItemChange(item.id)"></td>
            <td>{{item.name}}</td>
            <td>{{item.qty}}</td>
            <td>{{item.price | formatPrice}}</td>
            <td>{{item.price * item.qty | formatPrice}}</td>
            <td style="min-width: 120px;">
              <button type="button" class="btn btn-outline-success" @click="decrement(index)"
                v-bind:disabled="item.qty <= 1">-</button>
              <input type="number" min="1" :value="item.qty" class="form-control"
                style="width: 50px;display: inline-block;" @change="handelInput($event, index)">
              <button type="button" class="btn btn-outline-success" @click="increment(index)">+</button>
            </td>
            <td><button type="button" class="btn btn-outline-danger" @click="removeHandle(index)">remove</button></td>
          </tr>
          <tr>
            <td><input type="checkbox" @change="selectAll" :checked="allChecked">all</td>
            <td colspan="2" style="font-weight: bolder;" class="text-ali">TotalNum:{{totalNum}}</td>
            <td colspan="2" style="font-weight: bolder;" class="text-ali">TotalPrice:{{totalPrice | formatPrice}}</td>
            <td colspan="2"><button type="button" class="btn btn-danger" @click="resetList">Reset</button>
              <button type="button" class="btn btn-primary" @click="checkPrice">Checkout</button></td>
          </tr>
        </tbody>
      </table>
    </div>
    <!-- <h2 v-else>Empty</h2> -->
  </div>


  <script src="http://vuejs.org/js/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        list: [
          { id: 1, name: "Chicken Wing", category: "Food", qty: 3, price: 10, checked: true },
          { id: 2, name: "Pizza", category: "Food", qty: 5, price: 50, checked: true },
          { id: 3, name: "Hamburger", category: "Food", qty: 2, price: 12, checked: true },
          { id: 4, name: "Coca Cola", category: "Drink", qty: 1, price: 5, checked: true },
          { id: 5, name: "Orange Juice", category: "Drink", qty: 1, price: 15, checked: true },
          { id: 6, name: "Potato Chips", category: "Snack", qty: 8, price: 8, checked: true },
        ],
        allChecked: false,
        totalNum: 0,
        totalPrice: 0,
        // 当前选中的是哪个
        currentIndex: null,
      },
      methods: {
        increment(index) {
          this.list[index].qty++
          this.setCart(this.list)
        },
        decrement(index) {
          this.list[index].qty--
          this.setCart(this.list)
        },
        removeHandle(index) {
          let flag = confirm('您确定要删除吗?')
          if (flag) {
            this.list.splice(index, 1)
            this.setCart(this.list)
          }
        },
        resetList() {
          let flag = confirm('Are you sure you want to empty your shopping cart?')
          if (flag) {
            this.list = []
            this.allChecked = false
            this.setCart(this.list)
            this.currentIndex = null
          }
        },
        checkPrice() {
          if (this.list.length > 0) {
            alert('Please pay: ' + this.totalPrice)
          } else {
            alert('Please select the product')
          }
        },
        // 全选和非全选
        selectAll() {
          this.allChecked = !this.allChecked
          this.list.forEach(item => item.checked = this.allChecked)
          this.setCart(this.list)
        },

        // 单个商品的选中和不选中
        handelItemChange(id) {
          // 找到对应的商品取反
          const index = this.list.findIndex(item => item.id === id)
          this.list[index].checked = !this.list[index].checkedthis.setCart(this.list)
        },

        setCart(list) {
          let num = 0
          let price = 0
          let select = true
          list.forEach(item => {
            if (item.checked) {
              num += item.qty
              price += item.price * item.qty
            } else {
              select = false
            }
          })
          if (list.length === 0) {
            select = false
          }
          this.totalNum = num
          this.totalPrice = price
          this.allChecked = select
        },
        // sort by name
        sortName() {
          this.currentIndex = 1
          this.list.sort(function (a, b) {
            var nameA = a.name.toUpperCase(); // ignore upper and lowercase
            var nameB = b.name.toUpperCase(); // ignore upper and lowercase
            if (nameA < nameB) {
              return -1;
            }
            if (nameA > nameB) {
              return 1;
            }
            return 0;
          })
        },
        // sort by value
        sortQuality() {
          this.currentIndex = 2
          this.list.sort((a, b) => {
            // 顺序排列
            return (a.qty - b.qty)
          })
        },

        // 文本框输入数量
        handelInput(e, index) {
          this.list[index].qty = parseInt(e.target.value)
          this.setCart(this.list)
        },
      },
      mounted() {
        this.allChecked = this.list.length ? this.list.every(item => item.checked) : false
        this.setCart(this.list)
      },
      filters: {
        formatPrice(price) {
          return 'USD ' + price.toFixed(2)
        }
      },
    })
  </script>
</body>
</html>

 

posted @ 2020-06-19 18:33  yx1102  阅读(196)  评论(0编辑  收藏  举报