Vue2.0 购物车案例

微信公众号:二品翻译官
贵有恒何必三更起五更睡,最无益只怕一日曝十日寒!

购物车案例

1、导入、注册、使用Header组件① 安装node_moduels,启动serve服务② App.vue引入Header组件2、基于axios请求列表数据① 安装axios包② 导入axios,定义initCarList函数并进行调用3、只要请求回来的数据,在页面渲染期间要用到,则必须转存到data中4、循环渲染Goods组件① Goods组件封装title、pic、price、state属性② App.vue中渲染Goods组件5、修改商品勾选状态(子传父 自定义事件)① Goods.vue 追加id属性和自定义事件② App.vue接收自定义事件6、定义fullState全选状态① Footer.vue组件② App.vue引入Footer组件7、实现全选功能① Footer.vue 创建fullChange方法② App.vue接收全选状态8、计算商品总价格① Footer.vue追加自定义属性amount② App.vue追加计算属性amt9、把购买数量传给Counter.vue组件① Counter.vue追加自定义num属性② Goods.vue引入Counter.vue组件③ App.vue追加amt计算属性10、修改购买数量并传给App.vue① 在Components下创建eventBus.js② Counter.vue追加ID属性和add方法,同时调用eventBus功能③ App.vue生命周期created中追加bus接收11、动态计算勾选商品数量① Footer.vue追加all自定义属性② APP.vue汇总购买数量

1、导入、注册、使用Header组件

① 安装node_moduels,启动serve服务

E:\Demo\购物车案例\demo-cart> npm cache clear --force
E:\Demo\购物车案例\demo-cart> npm install
E:\Demo\购物车案例\demo-cart> npm run serve

② App.vue引入Header组件

<template>
...
    // 引入Header
    <Header></Header>
...
</template>

<script>
/* 引入Header */
import Header from '@/components/Header/Header.vue'
export default {
  components: {
    Header
  }
}
</script>

2、基于axios请求列表数据

① 安装axios包

E:\Demo\购物车案例\demo-cart> npm i axios -S

② 导入axios,定义initCarList函数并进行调用

<script>
...
import axios from 'axios'
export default {
  methods: {
    async initCarList(){
      const {data:res} = await axios.get('https://www.escook.cn/api/cart')
      console.log(res);
    }
  },
  created() {
    this.initCarList();
...
}
</script>

3、只要请求回来的数据,在页面渲染期间要用到,则必须转存到data中

<script>
...
export default {
  data(){
    return {
      list: []
    }
  },
  methods: {
    async initCarList(){
      const {data:res} = await axios.get('https://www.escook.cn/api/cart')
      if(res.status === 200){
        this.list = res.list
      }
    }
  },
...
</script>

4、循环渲染Goods组件

① Goods组件封装title、pic、price、state属性

<template>
...
    <input type="checkbox" class="custom-control-input" id="cb1" :checked="state" />
    <img :src="pic" alt="" />
    <h6 class="goods-title">{{title}}</h6>
    <span class="goods-price">¥{{price}}</span>
...
</template>
<script>
export default {
  props: {
    pic:   { default: '', type: String, },
    title: { default: '', type: String },
    price: { default: 0,type: Number},
    state: { default: true,type: Boolean}
  }
}
</script>

② App.vue中渲染Goods组件

<template>
  <div class="app-container">
    <Header></Header>
    <Goods v-for="item in list" :key="item.id" :pic="item.goods_img" :title="item.goods_name" 
          :state="item.goods_state" :price="item.goods_price"></Goods>
  </div>
</template>

<script>
...
import Goods from '@/components/Goods/Goods.vue'
...
  components: {
    Header,Goods
  }
}
</script>

5、修改商品勾选状态(子传父 自定义事件)

① Goods.vue 追加id属性和自定义事件

<template>
...
// 2、修改id属性 调用自定义changeState事件,复选框本身含有change事件
        <input type="checkbox" class="custom-control-input" :id="'cb'+id" :checked="state" @change="changeState"/>
        <label class="custom-control-label" :for="'cb'+id">
...
</template>

<script>
export default {
  props: {
// 1、追加ID属性
    id: {require: true,type: Number},
...
  methods: {
// 3、changeState自定义事件
    changeState(e){
      this.$emit('sendState',{id:this.id,flag:e.target.checked})
    }
  },
}
</script>

② App.vue接收自定义事件

<template>
  <div class="app-container">
// 1、接收自定义事件
    <Goods v-for="item in list" :key="item.id" :id="item.id" :pic="item.goods_img" 
          :title="item.goods_name" :state="item.goods_state" :price="item.goods_price"
          @sendState="getState"></Goods>
  </div>
</template>

<script>
...
  methods: {
...
// 2、创建接收函数
    getState(e){
      this.list.some(item=>{
        if(e.id === item.id){
          item.goods_state = e.flag;
          return true;
        }
      })
    }
  },
...
</script>

6、定义fullState全选状态

① Footer.vue组件

<template>
...
      <input type="checkbox" class="custom-control-input" id="cbFull" :checked="isFull" />
      <label class="custom-control-label" for="cbFull">全选</label>
...
</template>

<script>
export default {
  props: {
    isFull: {type: Boolean,default: true}
  }
}
</script>

② App.vue引入Footer组件

<template>
...
    <Footer :isFull="fullState"></Footer>
...
</template>

<script>
...
/* 4、引入Footer组件 */
import Footer from '@/components/Footer/Footer.vue'
export default {
 ...
// 通过计算属性 计算是否全选
  computed: {
    fullState(){
      return this.list.every(item=>item.goods_state)
    }
  },
// 注册Footer组件
  components: { Header,Goods,Footer }
}
</script>

7、实现全选功能

① Footer.vue 创建fullChange方法

<template>
...
      <input type="checkbox" class="custom-control-input" id="cbFull" :checked="isFull" @change="fullChange"/>
      <label class="custom-control-label" for="cbFull">全选</label>
...
</template>

<script>
export default {
....
  methods: {
    fullChange(e){
      this.$emit('sendFullChange',e.target.checked)
    }
  },
}
</script>

② App.vue接收全选状态

<template>
...
    <Footer :isFull="fullState" @sendFullChange="getFullChange"></Footer>
  </div>
</template>

<script>
export default {
  methods: {
    getFullChange(flag){
      this.list.forEach(item=>item.goods_state = flag)
    }
  },
...
</script>

8、计算商品总价格

① Footer.vue追加自定义属性amount

<template>
...
      <span class="total-price">¥{{ amount.toFixed(2) }}</span>
 ...
</template>

<script>
export default {
  props: {
    amount: {type: Number,default: 0}
  },
...
}
</script>

② App.vue追加计算属性amt

<template>
  <div class="app-container">
...
    <Footer :isFull="fullState" @sendFullChange="getFullChange" :amount="amt"></Footer>
  </div>
</template>

<script>
...
export default {
 ...
  computed: {
    amt(){
      return this.list.filter(item=>item.goods_state).reduce((total,item)=>(total+=item.goods_price*item.goods_count),0)
    }
  },
...
}

9、把购买数量传给Counter.vue组件

① Counter.vue追加自定义num属性

<template>
...
    <!-- 购买的数量 -->
    <span class="number-box">{{ num }}</span>
...
</template>

<script>
export default {
  props: {
    num: {default: 1,type: Number}
  }
}

② Goods.vue引入Counter.vue组件

<template>
...
        <!-- 商品的数量 -->
        <Counter :num="count" :id="id"></Counter>
...
</template>

<script>
import Counter from '@/components/Counter/Counter.vue'
export default {
  props: {
...
    count: { default: 1,type: Number}
  },
  components: {
    Counter
  }
}
</script>

③ App.vue追加amt计算属性

<template>
...
    <Footer :isFull="fullState" @sendFullChange="getFullChange" :amount="amt"></Footer>
...
</template>

<script>
...
export default {
...
  computed: {
...
    amt(){
      return this.list.filter(item=>item.goods_state).reduce((total,item)=>(total+=item.goods_price*item.goods_count),0)
    }
  },
...
</script>

10、修改购买数量并传给App.vue

① 在Components下创建eventBus.js

import Vue from 'vue'
export default new Vue()

② Counter.vue追加ID属性和add方法,同时调用eventBus功能

<template>
...
    <button type="button" class="btn btn-light btn-sm" @click="sub">-</button>
    <span class="number-box">{{ num }}</span>
    <button type="button" class="btn btn-light btn-sm" @click="add">+</button>
  </div>
</template>

<script>
import bus from '@/components/eventBus.js'

export default {
  props: {
    id: {require: true,type: Number},
    num: {default: 1,type: Number}
  },
  methods: {
    add(){
      bus.$emit('addNum',{id: this.id,value: this.num + 1})
    },
    sub(){
      if(this.num - 1 === 0) return
      bus.$emit('addNum',{id: this.id,value: this.num - 1})
    }
  },
}
</script>

③ App.vue生命周期created中追加bus接收

<script>
...
/* 5、引入eventBus */
import bus from '@/components/eventBus.js'

export default {
...
  created() {
    bus.$on('addNum',(val)=>{
      this.list.some((item)=>{
        if(item.id === val.id){
          item.goods_count = val.value;
          return true;
        }
      })
    })
  },
...
}
</script>

11、动态计算勾选商品数量

① Footer.vue追加all自定义属性

<template>
...
    <!-- 结算按钮 -->
    <button type="button" class="btn btn-primary btn-settle">结算({{ all }})</button>
...
</template>

<script>
export default {
  props: {
...
    all: {type:Number,default: 0}
  },
}
</script>

② APP.vue汇总购买数量

<template>
...
    <Footer :isFull="fullState" :all="total" :amount="amt"  @sendFullChange="getFullChange" ></Footer>
...
</template>

<script>
...
export default {
...
  computed: {
    total(){
      return this.list.filter(item=>item.goods_state).reduce((total,item)=>(total+=item.goods_count),0)
    }
  },
}
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值