我的购物小球是从'去结算'那里出来,请帮我看看为什么会这样

来源:17-20 购物车小球动画实现(3)

qq_上帝之手_3

2018-01-10

<template>

<div class="shopcart">

<div class="content">

<div class="content-left">

<div class="logo-wrapper">

<!-- :class="{'highLight':totalCount>0}"当totalCount>0时,只要我们选择了商品,显示class为highLight的样式 -->

<div class="logo" :class="{'highlight':totalCount>0}">

<i class="icon-shopping_cart" :class="{'highlight':totalCount>0}"></i>

</div>

<div class="num" v-show="totalCount>0">{{totalCount}}</div>

</div>

<div class="price" :class="{'highlight':totalPrice>0}">&yen;{{totalPrice}}元</div>

<div class="desc">另需配送费&yen;{{deliveryPrice}}元</div>

</div>

<div class="content-right">

<!-- 多少钱起送 -->

<div class="pay" :class="payClass">{{payDesc}}</div>

</div>

</div>

<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>

</div>

</template>

<script>

import BScroll from "better-scroll";

import cartcontrol from "components/cartcontrol/cartcontrol";


export default {

props: {

//shopcart组件传进来的变量要用props接收

selectFoods: {

//selectFoods保存了一个选择商品的数组,price就可以根据整个数组进行计算了

type: Array,

default() {

//如果default的值是Object或者Array,default就必需写成一个函数

return [

{

price: 30,

count: 1

}

]; //return一个空数组

}

},

deliveryPrice: {

type: Number, //变成习惯,prop属性一般最好指定数据类型

default: 0 //默认值是0

},

minPrice: {

type: Number,

default: 0

}

},

data() {

return {

balls: [

//抛物线小球需要创建一个数组

{

show: false

},

{

show: false

},

{

show: false

},

{

show: false

},

{

show: false

}

],

dropBalls: [], //已经下落的小球,数组//观测所有下落的小球

fold: true

};

},

computed: {

//利用计算属性表示price

totalPrice() {

//totalPrice依赖于selectFoods

let total = 0;

this.selectFoods.forEach(food => {

//遍历数组

total += food.price * food.count; //food指的是当前食物的数量

});

return total;

},

totalCount() {

let count = 0;

this.selectFoods.forEach(food => {

count += food.count; //把所有选择了的都加起来

});

return count;

},

payDesc() {

if (this.totalPrice === 0) {

//当总价是0的时候默认显示20元起送

return `&yen;${this.minPrice}元起送`; //用``代替用+号拼接字符串,写起来更加方便

} else if (this.totalPrice < this.minPrice) {

//当总价低于最低起送价时显示还差##元起送

let diff = this.minPrice - this.totalPrice; //声明一个变量说明离最低起送价还差多少

return `还差¥${diff}元起送`;

} else {

//剩下的就是满足条件的了

return "去结算"; //没有变量的时候就用普通的单引号就可以了

}

},

payClass() {

//根据实际情况切换enough或者not-enough的class属性

if (this.totalPrice < this.minPrice) {

return "not-enough";

} else {

return "enough";

}

}

},

methods: {

drop(el) {

//el指元素

console.log(el);

for (let i = 0; i < this.balls.length; i++) {

let ball = this.balls[i]; //拿到一个ball

if (!ball.show) {

//如果ball没有出现

ball.show = true;

ball.el = el;

this.dropBalls.push(ball); //将出现的ball加入dropBalls

return; //然后跳出循环

}

}

},

addFood(target) {

this.drop(target);

},

beforeEnter(el) {

let count = this.balls.length;

while (count--) {

let ball = this.balls[count];

if (ball.show) {

let rect = ball.el.getBoundingClientRect(); //获取小球的宽高

let x = rect.left - 32; //32是小球的left偏移

let y = -(window.innerHeight - rect.top - 22);

el.style.display = "";

el.style.webkitTransform = `translate3d(0,${y}px,0)`;

el.style.transform = `translate3d(0,${y}px,0)`;

let inner = el.getElementsByClassName("inner-hook")[0];

el.style.webkitTransform = `translate3d(${x}px,0,0)`;

el.style.transform = `translate3d(${x}px,0,0)`;

}

}

},

enter(el, done) {

//触发浏览器重绘,enter就重置回来

/*eslint-disable no-used-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];

el.style.webkitTransform = "translate3d(0,0,0)";

el.style.transform = "translate3d(0,0,0)";

el.addEventListener('transitionend', done);

});

},

afterEnter(el) {

let ball = this.dropBalls.shift();

if (ball) {

ball.show = false;

el.style.display = "none";

}

}

}

};

</script>

<style lang="stylus" type="stylesheet/stylus">

@import '../common/stylus/mixin.styl';

.shopcart

position: fixed

left: 0

bottom: 0

z-index: 50

width: 100%

height: 48px

.content

display: flex

background: #141d27

font-size: 0

color: rgba(255, 255, 255, 0.4)

.content-left

flex: 1

.logo-wrapper

display: inline-block

vertical-align: top

position: relative

top: -10px

margin: 0 12px

padding: 6px

width: 56px

height: 56px

box-sizing: border-box

border-radius: 50%

background: #141d27

.logo

width: 100%

height: 100%

border-radius: 50%

text-align: center

background: #2b343c

&.highlight

background: rgb(0, 160, 220)

.icon-shopping_cart

line-height: 44px

font-size: 24px

color: #80858a

&.highlight

color: #fff

.num

position: absolute

top: 0

right: 0

width: 24px

height: 16px

line-height: 16px

text-align: center

border-radius: 16px

font-size: 9px

font-weight: 700

color: #fff

background: rgb(240, 20, 20)

box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4)

.price

display: inline-block

vertical-align: top

margin-top: 12px

line-height: 24px

padding-right: 12px

box-sizing: border-box

border-right: 1px solid rgba(255, 255, 255, 0.1)

font-size: 16px

font-weight: 700

&.highlight

color: #fff

.desc

display: inline-block

vertical-align: top

margin: 12px 0 0 12px

line-height: 24px

font-size: 10px

.content-right

flex: 0 0 105px

width: 105px

.pay

height: 48px

line-height: 48px

text-align: center

font-size: 12px

font-weight: 700

&.not-enough

background: #2b333b

&.enough

background: #00b43c

color: #fff

.ball-container

.ball

position: fixed

left: 32px

bottom: 22px

z-index: 200

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

.shopcart-list

position: absolute

left: 0

top: 0

z-index: -1

width: 100%

transform: translate3d(0, -100%, 0)

&.fold-enter-active, &.fold-leave-active

transition: all 0.5s

&.fold-enter, &.fold-leave-active

transform: translate3d(0, 0, 0)

.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

overflow: hidden

background: #fff

.food

position: relative

padding: 12px 0

box-sizing: border-box

border-1px(rgba(7, 17, 27, 0.1))

.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


.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)

</style>

//我的购物小球是从'去结算'那里出来,请帮我看看为什么会这样,它现在是一条直线而不是抛物线

写回答

3回答

qq_上帝之手_3

提问者

2018-01-10

通过一行一行对代码,终于找到了原因,可以睡个安稳觉了,谢谢


0
0

qq_上帝之手_3

提问者

2018-01-10

beforeEnter(el) {//购物车小球动画重置

let count = this.balls.length;

while (count--) {

let ball = this.balls[count];

if (ball.show) {

let rect = ball.el.getBoundingClientRect(); //获取小球相对于视口的位置

let x = rect.left - 32; //32是小球的left偏移

let y = -(window.innerHeight - rect.top - 22);//获取y

el.style.display = '';

el.style.webkitTransform = `translate3d(0,${y}px,0)`;

el.style.transform = `translate3d(0,${y}px,0)`;

let inner = el.getElementsByClassName("inner-hook")[0];

inner.style.webkitTransform = `translate3d(${x}px,0,0)`;

inner.style.transform = `translate3d(${x}px,0,0)`;

}

}

},

//我已经改了beforeEnter(el) 的代码,它变成只能竖着掉小球了

0
1
ustbhuangyi
对比的代码包括 template 部分、JS 部分以及 CSS 部分,如果还有问题,建议单步调试。
2018-01-11
共1条回复

ustbhuangyi

2018-01-10

你这个代码贴的太难以阅读了,建议对比一下源码吧:https://github.com/ustbhuangyi/vue-sell

0
0

Vue.js2.5+cube-ui重构饿了么App(经典再升级)

掌握Vue1.0到2.0再到2.5最全版本应用与迭代,打造极致流畅的WebApp

9868 学习 · 4162 问题

查看课程