中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

VueshopCart組件開發(fā)詳解

一、shopCart組件

創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)整合營銷推廣、網(wǎng)站重做改版、江華網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、H5高端網(wǎng)站建設、購物商城網(wǎng)站建設、集團公司官網(wǎng)建設、成都外貿(mào)網(wǎng)站建設、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為江華等各大城市提供網(wǎng)站開發(fā)制作服務。

(1) goods 父組件和 子組件 shopCart 傳參

deliveryPrice:{ // 單價 從json seller 對象數(shù)據(jù)中獲取
 type:Number,
 default:0
},
minPrice:{ // 最低起送價 從json seller 對象數(shù)據(jù)中獲取
 type:Number,
 default:20
}

其中 deliveryPrice 和 minPrice 的數(shù)據(jù)都是從 data.json數(shù)據(jù) 中 seller 對象下 獲得。所以在goods 組件中還要 獲取到 seller對象 的數(shù)據(jù),否則會報錯:

[Vue warn]: Error in render: "TypeError: Cannot read property 'deliveryPrice' of undefined"

解決方法:根組件 App.vue 中 router-view 組件獲取seller 數(shù)據(jù),傳到 goods 組件中

1-1.app.vue (根組件 也是 goods 的父組件)

<keep-alive>
 <router-view :sell="sellerObj"></router-view>
</keep-alive>

注意:sellerObj 是data 定義 的 對象里用來接收 data.json 數(shù)據(jù),相當于 實參

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. 傳入用戶選中商品的集合

說明:從父組件會 傳入一個用戶選中商品的 數(shù)組,數(shù)組里會存放著 n 個對象,每個對象里存放著該 商品的 價格 和 數(shù)量。

props:{       // 通過父組件傳過來的 ( 相當于形參 )
 selefoodsArr:{   // 用戶選中的商品存放在一個數(shù)組里  接收的是 data.json數(shù)據(jù)的 goods(數(shù)組)
 type:Array, // 當父組件傳過來的 類型是對象或者 是數(shù)組時, default 就是一個函數(shù)
 default (){
 return []  // 返回數(shù)組 存放著選中 商品 對應的 goods下的 foods 數(shù)組(由 父組件 的 實參 決定的返回值)
 }
}

1-2. 利用計算屬性 選中商品數(shù)量的變化,商品總價,動態(tài)改變描述等功能

computed:{
 totalPrice (){     //計算總價,超過起送額度后提示可付款
 let total=0   // 定義一個返回值
 this.selefoodsArr.forEach((rfoods) =>{ // 遍歷 這個 goods 數(shù)組 取到 價格 和 數(shù)量 (當然在這里數(shù)據(jù)庫沒有count 這個屬性,稍后 我們會利用 vue.set() 新建一個count 屬性)
  total += rfoods.price * rfoods.count // 形參 rfoods 實參 是 foods
 });
 return total;
 },
 totalCount (){   // //計算選中的food數(shù)量,在購物車圖標處顯示,采用絕對定位,top:0;right:0;顯示在購物車圖標右上角  
 let count=0
 this.selefoodsArr.forEach((rfoods) =>{ // 形參 rfoods 實參 是 foods
  count += rfoods.count
 });
 return count;
 },
 payDesc (){    //控制底部右邊內(nèi)容隨food的變化而變化,payDesc()控制顯示內(nèi)容,enough 添加類調(diào)整顯示樣式
 let diff = this.minPrice - this.totalPrice
    if (!this.totalPrice) {
     return `¥${this.minPrice}起送`
    } else if (diff > 0) {
     return `還差¥${diff}元`
    } else {
     return '去結(jié)算'
    }
 }  
}

這樣就渲染到 template 里了

<div class="shopCart">
 <div class="content">
  <div class="content-left">
 <div class="logo-wrapper"> 
 <!--徽章 展示選中商品的個數(shù)-->
 <div class="badge" v-show="totalCount">
 {{totalCount}}
 </div>
 <!--購物車 圖標 選擇商品和未選擇商品 時 動態(tài)改變 樣式 條件:只要選擇了商品即總價不為0 ,樣式變--> 
  <div class="logo" :class="{'active':totalCount}">
   <i class="icon-shopping_cart"></i>
  </div>
 </div>
 <!--同理: 總價 不為0 字體高亮-->
 <div class="price" :class="{'active':totalPrice}">
  ¥{{totalPrice}}
 </div>
 <!--配送費 data.json 提供-->
 <div class="desc">
  另需要配送費¥{{deliveryPrice}}元
 </div>
  </div>
  <!--根據(jù)條件  動態(tài) 改變樣式-->
  <div class="content-right" :class="{'enough':totalPrice>=minPrice}">  
 {{payDesc}}  
 </div>
 </div>
</div>

相關樣式

&.active
  color white
  
&.enough
  background #00b43c
  color white

總結(jié):通過以上學習我們能發(fā)現(xiàn),selectFoods()的變化起著關鍵作用,它的變化會引起DOM的變化,并最終體現(xiàn)到界面上,而我們不用關注DOM內(nèi)部的具體實現(xiàn),這就是vue的一大好處。如果采用jQuery完成這些功能會略顯繁雜。

二、cartControl 組件

說明:這個組件是控制購物車小球的。其中涉及到小球的動畫

(1) 新增屬性 count

說明:

在goods 下的 foods 添加一個屬性 count,用來存儲用戶選中的商品個數(shù),計算商品總價 以及 關聯(lián)徽章(顯示用戶選擇商品的個數(shù))的變化

方法:通過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)添加按鈕 實現(xiàn)transtion 過渡

我們要實現(xiàn)的效果是:當點擊添加按鈕時,減少按鈕出現(xiàn) 并伴隨著 旋轉(zhuǎn)、平移以及透明度變化的 一些 動畫效果

<transition name='move'> <!--平移動畫-->  
 <div class="cart-decrease" v-show="foodsele.count" @click='decreaseCart($event)'>
  <span class="icon-remove_circle_outline inner"></span><!--旋轉(zhuǎn)、透明度動畫--> 
  </div>
</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旋轉(zhuǎn),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)

三、拋物線小球動畫

通過兩個層來控制小球,外層控制一個方向的變化,內(nèi)層控制另外一個方向的變化(寫兩層才會有拋物線的效果),采用fixed布局(是相對于視口的動畫)

事件發(fā)射和接收

組件之間傳值-1

組件之間傳值-2

擴展

Vue1.0組件間傳遞

  1. 使用$on()監(jiān)聽事件;
  2. 使用$emit()在它上面觸發(fā)事件;
  3. 使用$dispatch()派發(fā)事件,事件沿著父鏈冒泡;
  4. 使用$broadcast()廣播事件,事件向下傳導給所有的后代

(1) Vue2.0 組件之間傳遞數(shù)據(jù)

1-1. 當點擊 添加數(shù)量時 在 cartControl 組件里的 addCount 方法里 通過 $emit 屬性 派發(fā)一個事件 , 傳入點擊的對象

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++
 }
// 當點擊 添加數(shù)量時 通過 $emit 屬性 提交一個名為 add 給父組件
// 子組件通過 $emit觸發(fā) add事件 ,將參數(shù)傳遞給父組件
 this.$emit('add', event.target);
}

1-2. 操作 goods 組件

購物車組件如果提交了addCart事件就調(diào)用add函數(shù)

 <cart-control :foodsele='food' @add="addFood"></cart-control>

父組件使用 @add="addFood"監(jiān)聽由子組件vm.$emit觸發(fā)的事件,通過addFood()接受從子組件傳遞過來的數(shù)據(jù),通知父組件數(shù)據(jù)改變了。

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) {
  // 體驗優(yōu)化,異步執(zhí)行下落動畫
  this.$nextTick(() => {
   this.$refs.shopCart.balldrop(target);// 將target傳入shopCart子組件中的balldrop方法,所以drop方法能獲得用戶點擊按鈕的元素,即能獲取點擊按鈕的位置
  });
}  

區(qū)別 訪問DOM 變量

1-3. 操作 shopCart 組件

data (){ // 定義一個數(shù)組 來 控制小球的狀態(tài)  定義多個對象,表示頁面中做多同時運動的小球
 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 提供的鉤子函數(shù)

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];//內(nèi)層元素做橫向動畫,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(() => {//異步執(zhí)行
   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';
  }
 }
<div class="ball-container">
  <div v-for="ball in balls">
   <transition name="drop" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
    <div class="ball" v-show="ball.show">
     <div class="inner inner_hook"></div>
    </div>
   </transition>
  </div>
</div>
&.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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)頁名稱:VueshopCart組件開發(fā)詳解
當前鏈接:http://www.rwnh.cn/article24/ipcpce.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)頁設計公司面包屑導航、搜索引擎優(yōu)化、網(wǎng)站設計公司、品牌網(wǎng)站設計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設
鹤山市| 乡城县| 巴南区| 阿图什市| 收藏| 井冈山市| 崇左市| 宜黄县| 墨脱县| 石渠县| 汨罗市| 独山县| 聂拉木县| 同德县| 双峰县| 通城县| 汶川县| 潢川县| 上思县| 厦门市| 万山特区| 调兵山市| 西平县| 定兴县| 东莞市| 沛县| 故城县| 寿光市| 高雄县| 子洲县| 交口县| 绵竹市| 高青县| 观塘区| 广元市| 东平县| 衡山县| 昌黎县| 疏附县| 衢州市| 仙游县|