建立cartcontrol组件,组件关联到food的相关属性,价格,数量等,因此组件要props父组件goods传过来的food数据javascript
export default { //父组件传过来的,接收一个props属性来计算商品的个数,food.count,去goods组件中引入cartcontrol props: { food: { type: Object } }
布局:分三层,减小,数量num,增长,food.count>0时才会出现减小和数量的divcss
<div class="cartcontrol"> <transition name="fade"> <!-- 外层渐变,减号图标--> <div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart"> <transition name="inner"> <!-- 内层滚动,滚动时包含字体,字体在inner中--> <span class="inner icon-remove_circle_outline"></span> </transition> </div> </transition> <div class="cart-count" v-show="food.count > 0">{{food.count}}</div> <div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div> <!-- 加号图标 --> </div>
在goods中引入并注册组件,而后在模板里应用组件,每一个food的下边都有一个加减号组件,组件应包含在content中,即在价格的右边,并将food传入html
<div class="price"> <span class="now">¥{{food.price}}</span><span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span> </div> <div class="cartcontrol-wrapper"> <cartcontrol v-on:cart-add="cartAdd" :food="food"></cartcontrol> <!-- 传入food!!!--> </div>
并为cartcontrol-wrapper添加样式,将其固定在右侧vue
.cartcontrol-wrapper position absolute right 0 bottom 24px
在加减号组件中created中logs一下food,看是否能正确拿到food的值java
created() { // console.log(this.food); //忘记加this }
接下来给cartContronl写样式,简单的样式,没有添加动画json
以后在,加号部分添加一个点击事件,点击以后,改变food.count的值浏览器
<div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div> <!-- 加号图标 -->
由于goods组件中用了betterScroll组件,因此咱们在点击goods组件图层上的加减号组件时,不要忘了在初始化滚动组件的时候为其添加click:true容许点击app
在goods中初始化时:布局
this.foodsScroll = new BScroll(this.$refs.foodsWrapper, { click: true, probeType: 3 //BScroll滚动时,能实时告诉咱们滚动的位置,相似探针的效果 });
addCart(event) { //解决PC端双点击的问题 if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击 return; } //console.log('click');//点击不生效,不要忘了在foodScroll中添加click: true if (!this.food.count) { //food.count是原json中不存在的属性,不能直接添加 //this.food.count = 1; Vue.set(this.food, 'count', 1);//给this.food增长一个count属性,并初始化为1 } else { this.food.count++; } }
咱们发现咱们添加的约束条件当food.count>0时,并无出现数字和减号,这是由于count是food中不存在的属性,propty检测不到属性的变化, 咱们要为其添加count这个属性字体
import Vue from 'vue'; Vue.set(this.food, 'count', 1);//给this.food增长一个count属性,并初始化为1
给count添加css属性以后,count便可出现,并且咱们能够利用padding增长按钮的点击区域
.cart-count display inline-block vertical-align top width 12px padding-top 8px line-height 24px text-align center font-size 16px color rgb(147,153,159)
为减号添加一个点击事件
<div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart">
decreaseCart(event) { //解决PC端双点击的问题 if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击 return; } if (this.food.count) { this.food.count--; } }
最后,为加减号添加滚动的动画,点击加号的时候减号的按钮时从右到左滚动过来的,这样就有两个动画平移加滚动,还须要一个透明度从0到1的一个渐变过程,因此减组件须要两个层级,外层负责平移,内层负责滚动,表示字体的层应该放到内层
<transition name="fade"> <!-- 外层渐变,减号图标--> <div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart"> <transition name="inner"> <!-- 内层滚动,滚动时包含字体,字体在inner中--> <span class="inner icon-remove_circle_outline"></span> </transition> </div> </transition>
.cartcontrol font-size 0 // 消除incline-block中的空隙 .cart-decrease, .cart-add display inline-block // 横向排列 padding 6px // 图标较小,增长它的点击区域 &.fade-enter-active, &.fade-leave-active //进入动画的状态/离开动画时生效 transition: all 0.4s linear opacity 1 transform translate3d(0, 0, 0) &.fade-enter, &.fade-leave-active //动画的开始状态,动画一开始透明度要设为0/离开动画的结束状态 opacity: 0 transform translate3d(24px, 0, 0) .inner display inline-block //有宽高 line-height 24px font-size 24px vertical-align top color rgb(0, 160, 220, 0.2) &.inner-enter-active, &.inner-leave-active transition: all 0.4s linear opacity 1 transform: rotate(0) &.inner-enter, &.inner-leave-active opacity: 0 transform rotate(180deg)
咱们经过加减号组件修改了food的count属性,要将count的变化通知其父组件goods,而后goods经过计算得出selectFoods的变化,通知到购物车组件
首先在goods.vue中编写selectFoods,selectFoods组件要遍历全部的goods(计算属性),selectFood是一个计算属性,它观测的就是就是goods对象,goods发生变化他会从新计算进行更新
//用data绑定goods,以便后续添加到DOM中 data() { return { goods: [], listHeight: [], //存储区块的高度 }; }
selectFoods() { //遍历foods,看看选中了哪些商品 let foods = []; this.goods.forEach((good) => { //先取到每个分类 good.foods.forEach((food) => { //后取到每个分类下的不一样food if (food.count) { foods.push(food); //两层遍历,取到全部被选中的foods } }); }); return foods; //将结果传回到shopcart } }
再将selectFoods的结果传递到cartcontrol(购物车)组件中,这样,在点击加减号时改变了food的count属性,count的变化传回到父组件,而后在父组件中遍历goods下的foods,就取到了全部被选中的foods,将其返回值传递到shopCart中,就完成了加减号与购物车的同步联动
<shopcart ref="shopcart" :select-foods="selectFoods" :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice"></shopcart>
以后,为加减号添加动画小球的特效