須要使用better-scroll進行列表內容滾動綁定css
使用vue2的transition動畫過渡處理動畫html
使用子組件cartcontrol處理購物車的添加刪除操做cartcontrol.vue購物車操做按鈕vue
<!--transition是vue2的動畫格式--> <transition name="fold"> <div class="shopcart-list" v-show="listShow"> <div class="list-header"></div> <div class="list-content" ref="listContent"></div> </div> </transition>
一共有兩塊,list-header,list-content,這是根據設計稿內容肯定的css3
綁定清空按鈕segmentfault
<div class="list-header"> <h1 class="title">購物車</h1> <!--綁定empty方法清空購物車內容--> <span class="empty" @click="empty">清空</span> </div>
經過設置selectFoods裏面全部數據的count爲0來實現清空的目的數組
empty() { //清空購物車內容 this.selectFoods.forEach((food) => { food.count = 0; }); },
這裏也分開兩部分來講:app
第一部分:dom
使用ref來綁定一個dom,而後被vue使用,ref="listContent"
,這是爲了將list-content的dom被使用,而後實例化better-scroll實現滾動list的效果異步
購物車的清單是經過遍歷selectFoods數組(經過父組件goods處理並傳入goods.vue)獲得的,v-for="food in selectFoods"
ide
shopcart-list自己也有一個漸入漸出的動畫
list-content自己沒有高度,是靠header和content撐開
第二部分:
複用子組件cartcontrol,由於這個子組件在購物車內容和購物車詳情頁的列表裏都有使用,因此單獨獨立出來,複用代碼 <cartcontrol @add="addFood" :food="food"></cartcontrol>
子組件cartcontrol會有2個動畫,一個動畫是他本身自己的水平滾動,一個是動畫是要跟shopcart關聯的拋物線滾動cartcontrol.vue購物車操做按鈕
代碼部分:
html代碼
<!--ref是用來給better-scroll綁定的dom--> <div class="list-content" ref="listContent"> <ul> <!--遍歷selectFoods得到被勾選的全部數據--> <li class="food" v-for="food in selectFoods"> <span class="name">{{food.name}}</span> <div class="price"> <span>¥{{food.price * food.count}}</span> </div> <!--購物車詳情列表裏面的購物車按鈕組件cartcontrol--> <div class="cartcontrol-wrapper"> <cartcontrol @add="addFood" :food="food"></cartcontrol> </div> </li> </ul> </div>
js代碼
import BScroll from 'better-scroll'; //導入better-scroll import cartcontrol from '../../components/cartcontrol/cartcontrol'; //導入cartcontrol組件 export default{ //導出到當前vue文件內使用 props: { //父組件goods傳入數據 selectFoods: { //被勾選的全部foods的數據 type: Array, //默認值類型 default(){ //默認值,而且vue的data數據是一個函數寫法實現的 return [ {} ]; } }, }, data(){ return { fold: true // 控制購物車摺疊效果的標誌,默認是true表明摺疊 } }, computed: { totalCount(){ //在這裏被用來判斷購物車是否有東西 let count = 0; this.selectFoods.forEach((food) => { count += food.count; }) return count; }, listShow(){ //購物車是否展現內部列表處理 if (!this.totalCount) { //判斷沒有數量的狀況 this.fold = true; //摺疊屬性設置爲true,即摺疊起來,主要是更新fold的狀態 return false; //返回false是給v-show使用,false會display none } let show = !this.fold; //使用fold的狀態取反來實現經常使用的切換狀態處理邏輯 if (show) { //展現購物車列表內容 this.$nextTick(() => { //異步處理,提升體驗,防止卡頓 if (!this.scroll) { //若是沒有綁定過better-scroll就綁定一個 //用$refs來綁定vue的dom元素 this.scroll = new BScroll(this.$refs.listContent, { click: true //讓better-scroll將click事件也傳遞 }); } else { //使用better-scroll的內置事件refresh直接更新綁定,不用從新實例化一次better-scroll this.scroll.refresh(); } }); } return show; //返回布爾值給v-show使用 } }, methods: { toggleList(){ //封裝一個方法來控制購物車列表的顯示 if (!this.totalCount) { return; } this.fold = !this.fold; //切換狀態的處理 }, }, components: { cartcontrol //註冊cartcontrol組件,以便當前vue文件可以調用 }
css代碼
@import "../../common/stylus/mixin.styl" .shopcart-list position: absolute //由於須要固定在app主界面的底部(非footer) left: 0 top: 0 z-index: -1 //由於要避免遮擋footer的圖標 width: 100% transform: translate3d(0, -100%, 0) //設置css方式的vue動畫初始值,縱座標的-100%是指相反方向的當前元素的100%高度,這是"入" &.fold-enter-active, &.fold-leave-active //shopcart-list的漸入漸出動畫,這是"漸" transition: all 0.5s //所有元素0.5秒過渡變化 &.fold-enter, &.fold-leave-active // 這是"出" transform: translate3d(0, 0, 0) //3d變形 .list-header height: 40px line-height: 40px padding: 0 18px background: #f3f5f7 border-bottom: 1px solid rgba(7, 17, 27, 0.1) .title float: left font-size: 14px color: rgb(7, 17, 27) .empty float: right font-size: 12px color: rgb(0, 160, 220) .list-content padding: 0 18px max-height: 217px //由於不固定高度,因此用max-height overflow: hidden //要實現滾動,就要隱藏超出部分 background: #fff .food position: relative padding: 12px 0 box-sizing: border-box border-1px(rgba(7, 17, 27, 0.1))//要處理1px邊框問題,引入mixin.styl .name line-height: 24px font-size: 14px color: rgb(7, 17, 27) .price position: absolute right: 90px bottom: 12px line-height: 24px font-size: 14px font-weight: 700 color: rgb(240, 20, 20) .cartcontrol-wrapper position: absolute right: 0 bottom: 6px
<!--購物車詳情頁的遮罩而且動畫處理--> <transition name="fade"> <div class="list-mask" @click="hideList" v-show="listShow"></div> </transition>
hideList() { //遮罩隱藏 this.fold = true; },
遮罩的動畫是普通的漸隱漸現,使用css3實現
只須要操做數據屬性就可以實現
遮罩的層級是跟shopcart-list同級的,是由於同一層
遮罩觸發會放到shopcart組件的content元素,使用的方法是toggleList
.list-mask //遮罩的樣式 position: fixed top: 0 left: 0 width: 100% height: 100% z-index: 40 backdrop-filter: blur(10px) //遮罩虛化 opacity: 1 background: rgba(7, 17, 27, 0.6) &.fade-enter-active, &.fade-leave-active //遮罩動畫 transition: all 0.5s &.fade-enter, &.fade-leave-active opacity: 0 background: rgba(7, 17, 27, 0)