您好,欢迎访问一九零五行业门户网

Vue的shopCart组件使用方法

这次给大家带来vue的shopcart组件使用方法,使用vue的shopcart组件注意事项有哪些,下面就是实战案例,一起来看一下。
一、shopcart组件
(1) goods 父组件和 子组件 shopcart 传参
deliveryprice:{ // 单价 从json seller 对象数据中获取  type:number,  default:0 }, minprice:{ // 最低起送价 从json seller 对象数据中获取  type:number,  default:20 }
其中 deliveryprice 和 minprice 的数据都是从 data.json数据 中 seller 对象下 获得。所以在goods 组件中还要 获取到 seller对象 的数据,否则会报错:
[vue warn]: error in render: typeerror: cannot read property 'deliveryprice' of undefined
解决方法:根组件 app.vue 中 router-view 组件获取seller 数据,传到 goods 组件中
1-1.app.vue (根组件 也是 goods 的父组件)
<keep-alive>  <router-view :sell="sellerobj"></router-view> </keep-alive>
注意:sellerobj 是data 定义 的 对象里用来接收 data.json 数据,相当于 实参
1-2.goods.vue (相对于跟组件的子组件 且 shopcart 的父组件)
通过props 属性 进行组件之间的通信
props: {   sell: object // 相当于 形参  },
1-3.shopcart.vue ( goods 的子组件)
<shopcart :delivery-price="sell.deliveryprice" :min-price="sell.minprice"></shopcart>
(2) 选中商品 的 计算功能
1-1. 传入用户选中商品的集合
说明:从父组件会 传入一个用户选中商品的 数组,数组里会存放着 n 个对象,每个对象里存放着该 商品的 价格 和 数量。
props:{       // 通过父组件传过来的 ( 相当于形参 )  selefoodsarr:{   // 用户选中的商品存放在一个数组里  接收的是 data.json数据的 goods(数组)  type:array, // 当父组件传过来的 类型是对象或者 是数组时, default 就是一个函数  default (){  return []  // 返回数组 存放着选中 商品 对应的 goods下的 foods 数组(由 父组件 的 实参 决定的返回值)  } }
1-2. 利用计算属性 选中商品数量的变化,商品总价,动态改变描述等功能
computed:{  totalprice (){     //计算总价,超过起送额度后提示可付款  let total=0   // 定义一个返回值  this.selefoodsarr.foreach((rfoods) =>{ // 遍历 这个 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 '去结算'     }  }   }
这样就渲染到 template 里了
<p class="shopcart">  <p class="content">   <p class="content-left">  <p class="logo-wrapper">   <!--徽章 展示选中商品的个数-->  <p class="badge" v-show="totalcount">  {{totalcount}}  </p>  <!--购物车 图标 选择商品和未选择商品 时 动态改变 样式 条件:只要选择了商品即总价不为0 ,样式变-->    <p class="logo" :class="{'active':totalcount}">    <i class="icon-shopping_cart"></i>   </p>  </p>  <!--同理: 总价 不为0 字体高亮-->  <p class="price" :class="{'active':totalprice}">   ¥{{totalprice}}  </p>  <!--配送费 data.json 提供-->  <p class="desc">   另需要配送费¥{{deliveryprice}}元  </p>   </p>   <!--根据条件 动态 改变样式-->   <p class="content-right" :class="{'enough':totalprice>=minprice}>    {{paydesc}}    </p>  </p> </p>
相关样式
&.active   color white    &.enough   background #00b43c   color white
总结:通过以上学习我们能发现,selectfoods()的变化起着关键作用,它的变化会引起dom的变化,并最终体现到界面上,而我们不用关注dom内部的具体实现,这就是vue的一大好处。如果采用jquery完成这些功能会略显繁杂。
二、cartcontrol 组件
说明:这个组件是控制购物车小球的。其中涉及到小球的动画
(1) 新增属性 count
说明:
在goods 下的 foods 添加一个属性 count,用来存储用户选中的商品个数,计算商品总价 以及 关联徽章(显示用户选择商品的个数)的变化
方法:通过import vue from 'vue';使用set接口,通过vue.set()添加属性,当它变化时就能被检测到,从而父组件能获取到count值(遍历选中的商品时使用)
methods:{  addcart(event){ // 点击count 加,   //console.log(event.target);  if (!event._constructed) { // 去掉自带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 --   }    } }
(2)添加按钮 实现transtion 过渡
我们要实现的效果是:当点击添加按钮时,减少按钮出现 并伴随着 旋转、平移以及透明度变化的 一些 动画效果
<transition name='move'> <!--平移动画-->    <p class="cart-decrease" v-show="foodsele.count" @click='decreasecart($event)'>   <span class="icon-remove_circle_outline inner"></span><!--旋转、透明度动画-->    </p> </transition>
.cart-decrease   display inline-block   padding 6px   transition: all .4s linear  /*过渡效果的 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,0) /* 这样可以开启硬件加速,动画更流畅,3d旋转,x轴位移24px */    .inner        display inline-block  /* 设置成inline-block才有高度,才能有动画 */     transform rotate(0)   &.move-enter, &.move-leave-active    opacity: 0    transform translate3d(24px,0,0)    .inner     transform rotate(180deg)
三、抛物线小球动画
通过两个层来控制小球,外层控制一个方向的变化,内层控制另外一个方向的变化(写两层才会有抛物线的效果),采用fixed布局(是相对于视口的动画)
事件发射和接收
组件之间传值-1
组件之间传值-2
扩展
vue1.0组件间传递
使用$on()监听事件;
使用$emit()在它上面触发事件;
使用$dispatch()派发事件,事件沿着父链冒泡;
使用$broadcast()广播事件,事件向下传导给所有的后代
(1) vue2.0 组件之间传递数据
1-1. 当点击 添加数量时 在 cartcontrol 组件里的 addcount 方法里 通过 $emit 属性 派发一个事件 , 传入点击的对象
addcart(event){ // 点击count 加, //  console.log(event.target);  if (!event._constructed) { // 去掉自带click事件的点击     return;    }  if(!this.foodsele.count){  vue.set(this.foodsele, 'count', 1)  }else{  this.foodsele.count++  } // 当点击 添加数量时 通过 $emit 属性 提交一个名为 add 给父组件 // 子组件通过 $emit触发 add事件 ,将参数传递给父组件  this.$emit('add', event.target); }
1-2. 操作 goods 组件
购物车组件如果提交了addcart事件就调用add函数
<cart-control :foodsele='food' @add="addfood"></cart-control>
父组件使用 @add=addfood监听由子组件vm.$emit触发的事件,通过addfood()接受从子组件传递过来的数据,通知父组件数据改变了。
addfood(target) {   this._drop(target); }
1-3. 父组件访问子组件 vue 提供了接口 ref
复制代码 代码如下:
<shopcart ref="shopcart" :delivery-price="sell.deliveryprice" :min-price="sell.minprice" :selefoods-arr='selectfoods' ></shopcart>
_drop(target) {   // 体验优化,异步执行下落动画   this.$nexttick(() => {    this.$refs.shopcart.balldrop(target);// 将target传入shopcart子组件中的balldrop方法,所以drop方法能获得用户点击按钮的元素,即能获取点击按钮的位置   }); }
区别 访问dom 变量
1-3. 操作 shopcart 组件
data (){ // 定义一个数组 来 控制小球的状态  定义多个对象,表示页面中做多同时运动的小球  return{ // 定义 5 个 小球    balls:[{show:false},{show:false},{show:false},{show:false},{show:false}],  dropballs:[] // 接收下落小球   } }
methods:{  balldrop(ele) { // console.log(el) 取到点击 对象    for(var i=0;i<this.balls.length;i++){ let ball=this.balls[i] if(!ball.show){ ball.show=true ball.ele=ele this.dropballs.push(ball) return; } } } }
动画过程开始,利用vue 提供的钩子函数
beforeenter (el){ //找到所以设为true的小球 let count=this.balls.length while(count--){ let ball = this.balls[count]; if(ball.show){ let pos=ball.el.getboundingclientrect() //返回元素相对于视口偏移的位置 let x=pos.left-32 // 点击的按钮与小球(fixed)之间x方向的差值 let y=-(window.innerheight-pos.top-22) el.style.display = ''; //设置初始位置前,手动置空,覆盖之前的display:none,使其显示 el.style.webkittransform = `translate3d(0,${y}px,0)`; //外层元素做纵向的动画,y是变量 el.style.transform = `translate3d(0,${y}px,0)`; let inner = el.getelementsbyclassname('inner_hook')[0];//内层元素做横向动画,inner-hook(用于js选择的样式名加上-hook,表明只是用 //于js选择的,没有真实的样式含义) inner.style.webkittransform = `translate3d(${x}px,0,0)`; inner.style.transform = `translate3d(${x}px,0,0)`; } } }, enter(el) { /* eslint-disable no-unused-vars */ let rf = el.offsetheight; this.$nexttick(() => {//异步执行    el.style.webkittransform = 'translate3d(0,0,0)';  //重置回来    el.style.transform = 'translate3d(0,0,0)';    let inner = el.getelementsbyclassname('inner_hook')[0];    inner.style.webkittransform = 'translate3d(0,0,0)';    inner.style.transform = 'translate3d(0,0,0)';   });  },  afterenter(el) {   let ball = this.dropballs.shift(); //取到做完动画的球,再置为false,即重置,它还可以接着被利用   if (ball) {    ball.show = false;    el.style.display = 'none';   }  }
<p class="ball-container">   <p v-for="ball in balls">    <transition name="drop" @before-enter="beforeenter" @enter="enter" @after-enter="afterenter">     <p class="ball" v-show="ball.show">      <p class="inner inner_hook"></p>     </p>    </transition>   </p> </p>
&.drop-enter,&.drop-enter-active     transition all 0.4s cubic-bezier(0.49,-0.29,0.75,0.41)     .inner      width 16px      height 16px      border-radius 50%      background rgb(0,160,220)      transition all 0.4s linear
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
微信小程序开发图片压缩功能
js动态操作表格
js中object对象的原型的使用方法
以上就是vue的shopcart组件使用方法的详细内容。
其它类似信息

推荐信息