Vue.js学习笔记(一):简单书籍购物车

一、简介:

使用Vue.js实现简单的书籍购物车,包括以下功能:

  1. 书籍列表可显示当前商店里所上架书籍的信息:包括书名、价格和余量;点击书籍最后的“加入购物车”按钮,可将书籍加入到下方的书籍购物车;当余量为0时,不能进行加入购物车的操作;列表上方有可以搜索书籍的搜索框,输入书籍名包含的字即可实时显示相关书籍。
  2. 书籍购物车显示当前已经加入购物车内的书籍信息:包括书名、价格、数量;在数量中,有“+”和“-”两个按钮,可对书籍的数量进行增加或减少;点击书籍最后的“移除”按钮,可将该本书籍移除购物车;书籍购物车左上方有“清空购物车按钮”,点击该按钮会移除购物车中所有的书籍;当购物车中该本书的数量为1时,“-”操作不可用;当购物车中该本书的数量为该本书原来的余量,即现在书籍列表中该本书余量为0时,“+”操作不可用。
  3. 点击书籍后的“加入购物车”按钮,当购物车中已经存在相同的书籍时,“加入购物车”按钮和“+”按钮功能相同。
  4. 书籍列表和书籍购物车中的书籍数量会随着相应操作实时更新。
  5. 最下方显示当前书籍购物车中的总价格。

二、部分功能演示:

  1. 初始界面:
    在这里插入图片描述
  2. 搜索书籍
    在这里插入图片描述
  3. 加入书籍到购物车和增加数量
    在这里插入图片描述
    在这里插入图片描述

三、实现:

为阅读方便,将html、css和js代码放到一起。样式采用Bootstrap相关样式。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>书籍购物车</title>
  <!-- 导入 bootstrap.css 和 vue.js -->
  <link rel="stylesheet" type="text/css" href="lib/bootstrap.css">
  <script src="lib/vue.js"></script>
</head>
<body>
  <div id="app">
    <!-- 创建书籍列表 -->
    <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">书籍列表</h3>
      </div>
      <div class="panel-body">
        <label style="padding-left: 10px; margin-bottom: 10px" class="form-inline">
          搜索书籍:
          <!-- 将搜索框输入的内容使用v-model指令与keywords进行双向绑定 -->
          <input type="text" v-model="keywords" class="form-control">
        </label>
        <table class="table table-bordered table-hover" style="width: 60%">
          <thead>
          <tr>
            <th>书名</th>
            <th>价格</th>
            <th>余量</th>
            <th>操作</th>
          </tr>
          </thead>
          <tbody>
          <!-- 使用v-for指令遍历search方法中所得到的数组,并显示到书籍列表中(search方法实现见vue实例) -->
          <tr v-for="(item, index) in search(keywords)">
            <td>{{item.name}}</td>
            <td>{{item.price | showPrice}}</td>
            <td>{{item.count}}</td>
            <td>
              <!--  为加入购物车按钮绑定事件add(index), 同时动态绑定将disabled属性与书籍的数量绑定,当书籍的余量小于等于0时,该按钮不可用 -->
              <button class="btn btn-primary" @click="add(index)" :disabled="item.count <= 0">加入购物车</button>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>
    <!-- 创建书籍购物车 -->
    <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">书籍购物车</h3>
      </div>
      <div class="panel-body form-inline">
        <!-- 将清空购物车按钮与事件clear()绑定 -->
        <button class="btn btn-primary pull-right" @click="clear">清空购物车</button>

        <table class="table table-bordered table-hover" style="width: 60%">
          <thead>
          <tr>
            <th>书名</th>
            <th>价格</th>
            <th>数量</th>
            <th>操作</th>
          </tr>
          </thead>
          <tbody>
          <!--  遍历用户所选书籍数组,将其显示到书籍购物车中 -->
          <tr v-for="(item, index) in userBooks">
            <td>{{item.name}}</td>
            <!-- 使用过滤器显示价格 -->
            <td>{{item.price | showPrice}}</td>
            <td>
              <!-- "-"按钮绑定decrement(index),同时动态绑定将disabled属性与书籍的数量绑定,当购物车中书籍的数量小于等于0时,该按钮不可用 -->
              <button class="btn btn-primary" @click="decrement(index)" :disabled="item.count <= 1">-</button>
              {{item.count}}
              <!-- "+"按钮绑定increment(index),同时动态绑定将disabled属性与计算属性isAdd绑定,当该书籍余量为0时,该按钮不可用-->
              <button class="btn btn-primary" @click="increment(index)" :disabled="isAdd(index)">+</button>
            </td>
            <td>
              <!-- "移除"按钮绑定removeBook(index) -->
              <button class="btn btn-primary" @click="removeBook(index)">移除</button>
            </td>
          </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- 使用过滤器显示价格 -->
    <h4>总价格:{{ totalPrice | showPrice }}</h4>
  </div>
  <script>
    const vm = new Vue({
      el: '#app',
      data: {
        keywords: '',
        <!-- 书籍列表 -->
        books: [
          {id: 1, name: '人间失格', price: 25, count: 13},
          {id: 2, name: '活着', price: 28, count: 10},
          {id: 3, name: '三体(全三册)', price: 93, count: 3},
          {id: 4, name: '白夜行', price: 28, count: 5},
          {id: 5, name: '追风筝的人', price: 19, count: 11},
          {id: 6, name: '人生海海', price:55, count: 6}
        ],
        <!-- 书籍所选书籍列表 -->
        userBooks: [],
      },

      methods: {

        <!-- "+"按钮绑定事件:点击书籍数量加1 -->
        increment(index) {
          <!-- 找到index下标在书籍列表中所对应的书籍,并将其数量减1 -->
          for(let i of this.books){
            if(i.id === this.userBooks[index].id){
              i.count --;
            }
          }
          <!-- 将该书籍数量加1 -->
          this.userBooks[index].count ++;
        },

        <!-- "-"按钮绑定事件:点击书籍数量减1 -->
        decrement(index) {
          for(let i of this.books){
            if(i.id === this.userBooks[index].id){
              i.count ++;
            }
          }
          this.userBooks[index].count --;
        },

        <!-- "移除"按钮绑定事件:点击将该书籍从购物车中移除 -->
        removeBook (index) {
          <!-- 找到index下标在书籍列表中所对应的书籍,并将其数量改为现有数量加上购物车中的该书籍的数量 -->
          for(let i of this.books){
            if(i.id === this.userBooks[index].id){
              i.count += this.userBooks[index].count;
            }
          }
          <!-- 在用户所购书籍列表中删除该书籍 -->
          this.userBooks.splice(index, 1);
        },

        <!-- "加入购物车"按钮绑定事件:点击将该书籍加入购物车 -->
        add(index) {
          <!-- 若购物车中已有该书籍,则该按钮功能和"+"按钮相同 -->
          for (let item of this.userBooks){
            if(item.id === this.books[index].id){
              item.count ++;
              this.books[index].count --;
              return;
            }
          }
          <!-- 将新书籍加入购物车 -->
          let book = {};
          const returnedTarget = Object.assign(book, this.books[index]);
          book['count'] = 1;
          this.userBooks.push(book);
          this.books[index].count --;
        },

        <!-- "清空购物车"按钮绑定事件:点击将书籍购物车清空 -->
        clear() {
          <!-- 将购物车中的书籍数量重新加到书籍列表中 -->
          for (let i of this.userBooks){
            for(let j of this.books){
              if(i.id === j.id){
                j.count += i.count;
              }
            }
          }
          <!-- 清空用户所选书籍列表 -->
          this.userBooks.splice(0, this.userBooks.length);
        },

        <!-- 搜索书籍:把搜索框中的关键字keywords作为参数传给search -->
        <!-- 在search内部,通过for循环,把所有符合关键字的数据保存到一个新数组中返回 -->
        search(keywords) {
          return this.books.filter(item => {
            if (item.name.includes(keywords))
              return item;
          })
        },

      },

      computed: {
        <!-- 计算属性:总价格 -->
        <!-- 通过遍历用户所选书籍列表计算得到 -->
        totalPrice() {
          let price = 0;
          for(let i of this.userBooks){
            price += i.price * i.count;
          }
          return price;
        },
        <!-- 传入参数的计算属性:判断"+"按钮是否可用 -->
        isAdd() {
          return function (index) {
            for(let i of this.books){
              if(i.id === this.userBooks[index].id){
                if(i.count <= 0) {
                  return true;
                }
                else {
                  return false;
                }
              }
            }
          }
        }

      },
      <!-- 过滤器:价格显示为¥+保留两位小数的数字 -->
      filters: {
        showPrice(price) {
          return '¥' + price.toFixed(2);
        }
      }
    })
  </script>
</body>
</html>

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值