vue2.0实现购物车和地址选配功能

购物车案例功能:

  • 创建一个Vue实例
  • v-for渲染产品数据
  • Filter对金额和图片进行格式化
  • v-on实现产品金额的动态计算

功能比较简单,但是涉及到平时项目中常见的业务逻辑。可谓麻雀虽小,五脏俱全。

数据渲染

  1. vue-resource插件来获取后端数据(推荐使用vue-axios,官网说vue-resource已不再维护),这里用的是本地的json数据来模拟。引入vue.js ,vue-resource.js, 自己的js.
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="js/lib/vue-resource.js"></script>
<script src="js/cart1.js"></script>

cart.js中创建vue实例,data中声明个productList:[]来渲染数据,methods中声明函数cartView()来获取数据,mounted函数来执行这个cartView(mounted函数是el中的模板html,dom渲染完成再执行)

new Vue({
  el: '#app',
  data: {
    productList: []
  },
  mounted () {
    this.$nextTick(function () {
      this.cartView()
    })
  },  
  methods:{
    cartView() {
      this.$http.get('../data/cartData.json').then(res => {
        this.productList = res.data.result.list;
      })
    }
  }
})

注意我使用都是es6的写法,这里使用箭头函数,就不需要再获取父级作用域的this了。省略了var_ this = this
官网说,mounted函数应该这样使用保险一些:

mounted: function () {
  this.$nextTick(function () {
    // 代码保证 this.$el 在 document 中
  })
}

直接打开html是一定会出问题的,因为这里使用ajax来模拟获取后台数据产生了跨域,我使用了live-server插件来热启动,在本地的服务器上查看。

过滤器

使用过滤器来美化一下价格的样式,加上¥,并保留小数点2位。

  filters: {
    money(value, type) {
      return '¥' + value.toFixed(2) + type
    }
  },
<div class="item-price">{{item.productPrice | money('元')}}</div>

全局注册过滤器可以在其它页面引用,局部过滤器只能在这个实例中使用

Vue.filter('money', function (value, type) {
  return '$' + value.toFixed(2) + type
})

业务逻辑

  1. 商品数量的加减功能
  changeNumber(item, way) {
      if( way < 0) {
        item.productQuantity --;
        if(item.productQuantity < 1) {
          item.productQuantity = 1
        }
      }else{
        item.productQuantity ++;     
      }
    },
<a @click="changeNumber(item,-1)">-</a>
<input type="text" value="0" disabled  v-model="item.productQuantity">
<a @click="changeNumber(item, 1)">+</a>

changeNumber接受2个参数,第一个表示商品,第二个表示加或减

  1. 单选按钮的确认和取消

因为给的json数据里没有商品的选中和取消属性,我们就通过Vue.set来给商品注册这个属性,绑定class,如果为true,check样式就显示。并通过绑定点击事件来取反,来达到选择和取消。

 selectProduct(item) {
      if (typeof item.checked == 'undefined') {
        this.$set(item, 'checked', true)
      }else{
        item.checked = !item.checked
      }
    }
 <a  class="item-check-btn" :class="{'check': item.checked}" @click="selectProduct(item)">
  1. 全选按钮的确认和取消

这个功能我们就可以在data中注册个属性来表示。声明属性checkAll:false ,并绑定到class上,表示默认的是没有选中。绑定点击事件,传入参数true表示全选,此时checkAllFlag中this.checkAll = true,全选生效。同理,传入false,this.checkAll = false,取消全选

<span class="item-check-btn" :class="{'check':checkAll}" @click="checkAllFlag(true)">
<a class="item-del-btn" :class="{'check':checkAll}" @click="checkAllFlag(false)" >
checkAllFlag(flag) {
      this.checkAll = flag;
 }

那么,怎么通过全选达到商品也被选中的效果呢?

    checkAllFlag(flag) {
      this.checkAll = flag;
      this.productList.forEach((item, index) => {
        if(typeof item.checked == 'undefined') {
          this.$set(item, 'checked', flag)
        }else{
          item.checked = flag
        }
      })
    }

全选的时候,传入参数true,checkAll属性为true,同时,遍历商品的列表,给商品注册checked:true。取消全选同理。

  1. 总金额的计算

定义一个方法来计算总计额返回给data里的totalMoney.注意的是商品被选中的时,即item.checked为true时,totalMoney才计算。

   calcTotalMoney() {
      this.totalMoney = 0;
      this.productList.forEach((item, index) => {
        if(item.checked) {
          this.totalMoney += item.productPrice*item.productQuantity
        }
      })
    }
  1. 删除订单功能

data中声明delFlag默认为false,小垃圾桶图标绑定事件,删除界面v-bind:class=“{‘md-show’: delFlag}” ,md-show样式在delFlag=true的时候应用了。关闭按钮绑定点击事件delFlag=false,这里注意的是有一个遮罩层,用v-if=“delFlag”来控制显示和隐藏。

小垃圾桶绑定事件delConfirm(item),让curProduct变量来保存此时的商品item。

    delConfirm(item) {
      this.delFlag = true;
      this.curProduct = item //声明curProduct属性来保存此时的item
    },

然后在删除功能中,获取这个商品item的index,再用splice方法删除。

    delProduct() {
      var index = this.productList.indexOf(this.curProduct)
      this.productList.splice(index, 1);
      this.delFlag = false
    }

好了,到这里,购物车的一些基本功能基本上都实现了。

地址选配功能

跟购物车功能类似,或许数据,挂在到mounted函数上,这里不同的是用计算属性computed获取数组的3项,然后在dom中渲染,

   computed: {
        filterAddress: function () {
            return this.addressList.slice(0, this.limitNum) //获取addressList的前三个
        }
    },
 <li v-for="(item,index) in filterAddress" ></li>

列表选项问题,配送方式的点击选中如下实现:

 <li :class="{'check':shippingMethod == 1}" @click="shippingMethod = 1">
    <div class="name">标准配送</div>
    <div class="price">Free</div>
</li>
 <li :class="{'check':shippingMethod == 2}" @click="shippingMethod = 2">
    <div class="name">高级配送</div>
    <div class="price">180</div>
</li>

地址列表如下实现:

 <li v-for="(item,index) in filterAddress"  :class="{'check': index == currentIndex}"  @click="currentIndex = index">

点击此地址,将索引index赋值给currentIndex,那么cunrrentIndex==index成立时,check样式实现。
这里是很好的2种不同情况下的实现方式,在以后的项目中可能会经常遇到。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、基础知识 1、创建vue实例 2、常用指令 {{}}实现数据绑定 v-model 双向数据绑定,用于input...
    飞飞廉阅读 604评论 0 0
  • Vuejs2.0购物车和地址选配学习笔记 按照慕课网的Vuejs2.0的学习视频零基础实践的一个demo如下:演示...
    fleeming阅读 370评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,890评论 18 139
  • 雨后的彩虹 于一个平常的傍晚出现 让夏天 仿若邻家女孩般 不经意间来到眼前 不甘寂寞的蝉 用一往深情的嘶鸣 竭力唤...
    遥远的星光阅读 708评论 0 4
  • 一村忆 一城雨 我不甘 我不愿一次一声一失去 我不想一梦一雨一放弃 能 绝不松手 即使失败又怎样 泪下三尺血流两步...
    愁忧情阅读 244评论 0 0