1、使用自定义事件

思路:
1、自定义事件传值,首页写了addToCart和 delFromCart两个方法,并且在mounted里用 进行自定义事件绑定,子组件调用使用event.$emit
2、购物车循环的数据列表list是通过父组件传给的productionList和cartList计算所得,用map方法嵌套find方法,返回一个新数据赋给list数组,里面包含id,price,quantity
3、总价是用reduce函数计算所得
cart/index.vue
<template>
<div>
<ProductionList :list="productionList"/>
<hr>
<CartList
:productionList="productionList"
:cartList="cartList"
/>
</div>
</template>
<script>
import ProductionList from './ProductionList/index'
import CartList from './CartList/index'
import event from './event'
export default {
components: {
ProductionList,
CartList
},
data() {
return {
productionList: [
{
id: 1,
title: '商品A',
price: 10
},
{
id: 2,
title: '商品B',
price: 15
},
{
id: 3,
title: '商品C',
price: 20
}
],
cartList: [
{
id: 1,
quantity: 1 // 购物数量
}
]
}
},
methods: {
// 加入购物车
addToCart(id) {
// 先看购物车中是否有该商品
const prd = this.cartList.find(item => item.id === id)
if (prd) {
// 数量加一
prd.quantity++
return
}
// 购物车没有该商品
this.cartList.push({
id,
quantity: 1 // 默认购物数量 1
})
},
// 从购物车删除一个(即购物数量减一)
delFromCart(id) {
// 从购物车中找出该商品
const prd = this.cartList.find(item => item.id === id)
if (prd == null) {
return
}
// 数量减一
prd.quantity--
// 如果数量减少到了 0
if (prd.quantity <= 0) {
this.cartList = this.cartList.filter(
item => item.id !== id
)
}
}
},
mounted() {
event.$on('addToCart', this.addToCart)
event.$on('delFromCart', this.delFromCart)
}
}
</script>
cart/cartlist/index.vue
<template>
<div>
<CartItem
v-for="item in list"
:key="item.id"
:item="item"
/>
<p>总价 {{totalPrice}}</p>
</div>
</template>
<script>
import CartItem from './CartItem'
export default {
components: {
CartItem,
},
props: {
productionList: {
type: Array,
default() {
return [
// {
// id: 1,
// title: '商品A',
// price: 10
// }
]
}
},
cartList: {
type: Array,
default() {
return [
// {
// id: 1,
// quantity: 1
// }
]
}
}
},
computed: {
// 购物车商品列表
list() {
return this.cartList.map(cartListItem => {
// 找到对应的 productionItem
const productionItem = this.productionList.find(
prdItem => prdItem.id === cartListItem.id
)
// 返回商品信息,外加购物数量
return {
...productionItem,
quantity: cartListItem.quantity
}
// 如:
// {
// id: 1,
// title: '商品A',
// price: 10,
// quantity: 1 // 购物数量
// }
})
},
// 总价
totalPrice() {
return this.list.reduce(
(total, curItem) => total + (curItem.quantity * curItem.price),
0
)
//reduce(function(prev, cur) {
// return cur.score + prev;
//}, 0)
}
}
}
</script>
cart/cartlist/cartitem.vue
<template>
<div>
<span>{{item.title}}</span>
<span>(数量 {{item.quantity}})</span>
<a href="#" @click="addClickHandler(item.id, $event)">增加</a>
<a href="#" @click="delClickHandler(item.id, $event)">减少</a>
</div>
</template>
<script>
import event from '../event'
export default {
props: {
item: {
type: Object,
default() {
return {
// id: 1,
// title: '商品A',
// price: 10,
// quantity: 1 // 购物数量
}
}
}
},
methods: {
addClickHandler(id, e) {
e.preventDefault()
event.$emit('addToCart', id)
},
delClickHandler(id, e) {
e.preventDefault()
event.$emit('delFromCart', id)
}
}
}
</script>
cart/productionlist/index.vue
<template>
<div>
<ProductionItem
v-for="item in list"
:key="item.id"
:itemdd="item"
/>
</div>
</template>
<script>
import ProductionItem from './ProductionItem'
export default {
components: {
ProductionItem,
},
props: {
list: {
type: Array,
default() {
return [
// {
// id: 1,
// title: '商品A',
// price: 10
// }
]
}
}
}
}
</script>
cart/productlist/productitem.vue
<template>
<div>
<span>{{itemdd.title}}</span>
<span>{{itemdd.price}}元</span>
<a href="#" @click="clickHandler(itemdd.id, $event)">加入购物车</a>
</div>
</template>
<script>
import event from '../event'
export default {
name: 'HomeHeader1',
props: {
itemdd: {
type: Object,
default() {
return {
// id: 1,
// title: '商品A',
// price: 10
}
}
}
},
methods: {
clickHandler(id, e) {
e.preventDefault()
event.$emit('addToCart', id)
}
},
}
</script>