shopchart中的methods,el打印不出来,购物小球后续的操作都没办法做了

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

qq_上帝之手_3

2018-01-10

//goods.vue

<template>

<div class="goods">

<div class="menu-wrapper" ref='menuWrapper'>

<ul>

<!-- 当当前轮到的$index是当前的index的时候,给它添加一个current的样式,设置高亮 -->

<!-- 点击事件selectMenu在methods里面定义 -->

<li v-for="(item,$index) in goods" class="menu-item" :class="{'current':currentIndex===$index}"

@click="selectMenu($index,$event)">

<span class="text border-1px">

<span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>{{item.name}}

</span>

</li>

</ul>

</div>

<div class="foods-wrapper" ref='foodsWrapper'>

<ul>

<li v-for="item in goods" class="food-list" ref="foodList">

<h1 class="title">{{item.name}}</h1>

<ul>

<li v-for="food in item.foods" class="food-item">

<div class="icon">

<img width="57" height="57" :src="food.icon">

</div>

<div class="content">

<h2 class="name">{{food.name}}</h2>

<p class="desc">{{food.description}}</p>

<div class="extra">

<span class="count">月售{{food.sellCount}}份</span>

<span>好评率{{food.rating}}%</span>

</div>

<div class="price">

<span class="now">&yen;{{food.price}}</span>

<span v-show="food.oldPrice" class="old">&yen;{{food.oldPrice}}</span>

</div>

<div class="cartcontrol-wrapper">

<!-- cartcontrol组件,把food传入关联 -->

<cartcontrol :food="food"></cartcontrol>

</div>

</div>

</li>

</ul>

</li>

</ul>

</div>

<!-- 组件 -->

<!-- 如果这里写了:deliveryPrice="seller.deliveryPrice" :minPrice="seller.minPrice"却

   还是报错,记得去app.vue的router-view标签设:seller="seller"属性传递拥有的数据 -->

<shopcart ref="shopcart" :select-foods="selectFoods" :deliveryPrice="seller.deliveryPrice" :minPrice="seller.minPrice"></shopcart>

</div>


</template>


<script type="text/ecmascript-6">

import shopcart from "../shopCart/shopCart.vue"; //import~之后记得在components里面注册这个组件

import cartcontrol from "../cartcontrol/cartcontrol.vue"; //import~之后记得在components里面注册这个组件

import BScroll from "better-scroll"; //接受BSroll实例化的时候要接受一个dom

const ERR_OK = 0;

export default {

props: {

seller: {

type: Object

}

},

data() {

return {

goods: [],

listHeight: [], //用一个变量来存滚动屏幕高度的数据

scrollY: 0, //跟踪y方向上的变量

selectedFood: {}

};

},

computed: {

//计算属性

currentIndex() {

//左侧当前的索引

for (var i = 0; i < this.listHeight.length; i++) {

//获得当前索引值对应的高度

let height1 = this.listHeight[i];

let height2 = this.listHeight[i + 1];

//height1he height2分别对应一个区间的高点和低点

if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) {

//如果是最后一个或者是落在当前正常高度区间

return i;

}

}

return 0; //如果什么都没有就返回0

},

selectFoods() {

//:select-foods="selectFoods"要的数据从这里找

//select-foods它观测的是goods这个对象,goods发生变化以后就会被重新计算,重新计算,以下的逻辑会再被执行一遍

let foods = [];

this.goods.forEach(good => {

good.foods.forEach(food => {

if (food.count) {

//如果这个商品的count值有的话,就加入到foods数组中

foods.push(food);

}

});

});

return foods; //return foods给selectFoods,这样就能让cartcontrol和和购物车shopcart联动了

}

},

created() {

this.classMap = [

"decrease",

"discount",

"guarantee",

"special",

"invoice",

"guarantee"

];

this.$http.get("../static/data.json").then(res => {

// if (response.errno === ERR_OK) {

this.goods = res.data.goods;

console.log(this.goods);

this.$nextTick(() => {

this._initScroll();

this._calculateHeight(); //定义求滚动屏幕高度的方法

});

// }

});

},

methods: {

//方法属性

selectMenu($index, $event) {

//$event指的是click所传递的事件


//在better-scroll里面派发的事件和原生event事件有一个属性区别,

//当属于我们(better-scroll)自己派发出来的事件的时候$event._constructed是true,

//而pc端浏览器原生里是没有_constructed这个属性的,所以如果是浏览器一生的点击事件要设置!$event._constructed,

//当!$event._constructed的时候return不执行

//只有当我们自定义事件派发的时候$event._constructed为true,就会走到下面的逻辑


if (!$event._constructed) {

return; //

}

console.log($index);

// console.log($event);

let foodList = this.$refs.foodList; //拿到所有的foodList列表

let el = foodList[$index]; //拿到el的dom元

this.foodsScroll.scrollToElement(el, 300); //滚动的接口scrollToElement,传入滚动的dom元素el和滚动的动画时间300毫秒

},

_drop(target) {

// 体验优化,异步执行下落动画

this.$nextTick(() => {//通过$refs访问子组件对象

this.$refs.shortcart.drop(target);//通过this.$refs.shortcart访问到子组件,调用它的drop方法同时把它的子组件传进去

});

},

_initScroll() {

this.meunScroll = new BScroll(this.$refs.menuWrapper, {

click: true //因为better-scroll(实现原理是监听了一些touchstart,touchend事件)会阻止默认事件click,所以要设置一下点击事件才能阻止默认的事件

});


this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {

click: true,

probeType: 3 //希望滚动的时候实时告诉我们滚动的位置,相当于探针的效果

});

this.foodsScroll.on("scroll", pos => {

this.scrollY = Math.abs(Math.round(pos.y)); //scrollY必须是正值,所以用绝对值函数,实时拿到scrollY,接下来是把scrollY和左侧的索引做映射

});

},

_calculateHeight() {

let foodList = this.$refs.foodList;

let height = 0;

this.listHeight.push(height); //先拿到第0个的高度

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

let item = foodList[i];

height += item.clientHeight;

this.listHeight.push(height); //其实是一个区间数组,它标识着每个区间的高度

}

}

},

components: {

//注册shopcart组件,这样页面才看得到,模板才可以使用这个组件

shopcart,

cartcontrol, //注册组件

// food

},

events: {//先在cartcontrol用$emit传递时间,再在这里写事件

//这里需要调用子组件的方法

'cart.add'(target) {

console.log(target);

//cart.add事件

this._drop(target); //把target传进来

}

}

};

//shopcart.vue

<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" v-show="ball.show" transiton="drop" class="ball">

<div class="inner inner-hook"></div>

</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);

}

}

};

//cartcontrol.vue

<template>

<div class="cartcontrol">

<transition name="move">

<div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart" transition="move">

<span class="inner icon-remove_circle_outline"></span>

</div>

</transition>

<div class="cart-count" v-show="food.count>0">{{food.count}}</div>

<div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div>

</div>

</template>

<script>

import Vue from 'vue';//引入全局vue

export default{

props:{

food:{

type:Object

}

},

created(){

// console.log(this.food);

},

methods:{

addCart(event){

if(!event._constructed){

return;

}

// console.log('click');

if (!this.food.count) {//判断food.count是否存在

Vue.set(this.food,'count',1);//给vue增加一个count属性,同时设为1;

//通过Vue.set()添加的属性vue就能观测到

// this.food.count=1;

}else{

this.food.count++;

}

this.$emit('cart.add', event.target);//派发cart.add事件

},

decreaseCart(event){

if(!event._constructed){

return;

}

// console.log('click');

if (this.food.count) {//判断food.count是否存在,有就减

this.food.count--;

}

}

}

};


写回答

1回答

qq_上帝之手_3

提问者

2018-01-10

已经可以打印了,谢谢

1
1
Chuihunzhe
我 还是打印不出来啊 可以说说你的经验吗
2018-03-02
共1条回复

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

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

9868 学习 · 4162 问题

查看课程