Vue shopCart 组件开发详解
前端之家收集整理的这篇文章主要介绍了
Vue shopCart 组件开发详解,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_3010@一、shopCart组件
@H
301_0@(1) goods 父组件和 子组件 shopCart 传参
<div class="jb51code">
<pre class="brush:js;">
deliveryPrice:{ // 单价 从json seller 对象数据中
获取
type:Number,default:0
},minPrice:{ // 最低起送价 从json seller 对象数据中
获取
type:Number,default:20
}
@H_
301_0@其中 deliveryPrice 和 minPrice 的数据都是从 data.json数据 中 seller 对象下 获得。所以在goods 组件中还要
获取到 seller对象 的数据,否则会报错:
@H_301_0@[Vue warn]: Error in render: "TypeError: Cannot read property 'deliveryPrice' of undefined"
@H_
301_0@
解决方法:根组件 App.vue 中 router-view 组件
获取seller 数据,传到 goods 组件中
@H_
301_0@1-1.app.vue (根组件 也是 goods 的父组件)
@H_
301_0@注意:sellerObj 是data 定义 的 对象里用来接收 data.json 数据,相当于 实参
@H_
301_0@1-2.goods.vue (相对于跟组件的子组件 且 shopCart 的父组件)
@H_
301_0@通过props
属性 进行组件之间的通信
@H_
301_0@1-3.shopCart.vue ( goods 的子组件)
@H_
301_0@(2) 选中商品 的 计算
功能
@H_
301_0@1-1. 传入
用户选中商品的集合
@H_
301_0@说明:从父组件会 传入一个
用户选中商品的 数组,数组里会存放着 n 个对象,每个对象里存放着该 商品的 价格 和
数量。
用户选中的商品存放在一个数组里 接收的是 data.json数据的 goods(数组)
type:Array,// 当父组件传过来的 类型是对象或者 是数组时, default 就是一个
函数
default (){
return [] // 返回数组 存放着选中 商品 对应的 goods下的 foods 数组(由 父组件 的 实参 决定的返回值)
}
}
@H_
301_0@1-2. 利用计算
属性 选中商品
数量的变化,商品总价,动态改变描述等
功能
{ // 遍历 这个 goods 数组 取到 价格 和
数量 (当然在这里
数据库没有count 这个
属性,稍后 我们会利用 vue.set() 新建一个count
属性)
total += rfoods.price * rfoods.count // 形参 rfoods 实参 是 foods
});
return total;
},totalCount (){ // //计算选中的food
数量,在购物车图标处
显示,采用绝对定位,top:0;right:0;
显示在购物车图标右上角
let count=0
this.selefoodsArr.forEach((rfoods) =>{ // 形参 rfoods 实参 是 foods
count += rfoods.count
});
return count;
},payDesc (){ //控制
底部右边
内容随food的变化而变化,payDesc()控制
显示内容,enough
添加类调整
显示样式
let diff = this.minPrice - this.totalPrice
if (!this.totalPrice) {
return `¥${this.minPrice}起送`
} else if (diff > 0) {
return `还差¥${diff}元`
} else {
return '去结算'
}
}
}
@H_
301_0@这样就渲染到 template 里了
logo-wrapper">
logo" :class="{'active':totalCount}">
@H_
301_0@相关样式
&.enough
background #00b43c
color white
@H_
301_0@总结:通过以上学习我们能发现,selectFoods()的变化起着关键作用,它的变化会引起DOM的变化,并最终体现到界面上,而我们不用关注DOM内部的具体实现,这就是vue的一大好处。如果采用jQuery完成这些
功能会略显繁杂。
@H_
301_0@
二、cartControl 组件
@H_
301_0@说明:这个组件是控制购物车小球的。其中涉及到小球的动画
@H_
301_0@(1) 新增
属性 count
@H_
301_0@说明:
@H_
301_0@在goods 下的 foods
添加一个
属性 count,用来存储
用户选中的商品个数,计算商品总价 以及 关联徽章(
显示用户选择商品的个数)的变化
@H_
301_0@
方法:通过import Vue from 'vue';使用set接口,通过vue.set()
添加属性,当它变化时就能被检测到,从而父组件能
获取到count值(遍历选中的商品时使用)
自带click事件的点击
return;
}
if(!this.foodsele.count){
Vue.set(this.foodsele,'count',1)
}else{
this.foodsele.count++
}
},decreaseCart (event){ // 点击减少
if (!event._constructed) { // 去掉
自带click事件的点击
return;
}
if(this.foodsele.count){
this.foodsele.count --
}
}
}
@H_
301_0@(2)
添加按钮 实现transtion 过渡
@H_
301_0@我们要实现的
效果是:当点击
添加按钮时,减少按钮出现 并伴随着 旋转、平移以及透明度变化的 一些 动画
效果
效果的 CSS
属性的
名称、过渡
效果需要多少时间、速度
效果的速度曲线*/
.inner
line-height 24px
font-size 24px
color rgb(0,160,220)
transition all 0.4s linear
&.move-enter-active,&.move-leave-active
transform translate3d(0,0) /* 这样可以开启硬件加速,动画更流畅,3D旋转,X轴位移24px */
.inner
display inline-block /* 设置成inline-block才有高度,才能有动画 */
transform rotate(0)
&.move-enter,&.move-leave-active
opacity: 0
transform translate3d(24px,0)
.inner
transform rotate(180deg)
@H_
301_0@
三、抛物线小球动画
@H_
301_0@通过两个层来控制小球,外层控制一个方向的变化,内层控制另外一个方向的变化(写两层才会有抛物线的
效果),采用fixed布局(是相对于视口的动画)
@H_
301_0@事件发射和接收
@H_
301_0@
@H_301_0@
扩展
@H_
301_0@Vue1.0组件间传递
- 使用$on()监听事件;
- 使用$emit()在它上面触发事件;
- 使用$dispatch()派发事件,事件沿着父链冒泡;
- 使用$broadcast()广播事件,事件向下传导给所有的后代
@H_
301_0@(1) Vue2.0 组件之间传递数据
@H_
301_0@1-1. 当点击
添加数量时 在 cartControl 组件里的 addCount
方法里 通过 $emit
属性 派发一个事件,传入点击的对象
自带click事件的点击
return;
}
if(!this.foodsele.count){
Vue.set(this.foodsele,1)
}else{
this.foodsele.count++
}
// 当点击
添加数量时 通过 $emit
属性 提交一个名为 add 给父组件
// 子组件通过 $emit触发 add事件 ,将参数传递给父组件
this.$emit('add',event.target);
}
@H_
301_0@1-2. 操作 goods 组件
@H_
301_0@购物车组件如果提交了addCart事件就
调用add
函数
@H_
301_0@父组件使用 @add="addFood"监听由子组件vm.$emit触发的事件,通过addFood()接受从子组件传递过来的数据,
通知父组件数据改变了。
@H_
301_0@1-3. 父组件访问子组件 vue 提供了接口 ref
@H_
301_0@
{
this.$refs.shopCart.balldrop(target);// 将target传入shopCart子组件中的balldrop
方法,所以drop
方法能获得
用户点击按钮的元素,即能
获取点击按钮的位置
});
}
@H_
301_0@
区别 访问DOM 变量
@H_
301_0@1-3. 操作 shopCart 组件
页面中做多同时运动的小球
return{ // 定义 5 个 小球
balls:[{show:false},{show:false},{show:false}],dropBalls:[] // 接收下落小球
}
}
@H_
301_0@动画过程开始,利用vue 提供的
钩子函数
{//异步执行
el.style.webkitTransform = 'translate3d(0,0)'; //重置回来
el.style.transform = 'translate3d(0,0)';
let inner = el.getElementsByClassName('inner_hook')[0];
inner.style.webkitTransform = 'translate3d(0,0)';
inner.style.transform = 'translate3d(0,0)';
});
},afterEnter(el) {
let ball = this.dropBalls.shift(); //取到做完动画的球,再置为false,即重置,它还可以接着被利用
if (ball) {
ball.show = false;
el.style.display = 'none';
}
}