vue组件化购物车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div class=container>
<my-cart></my-cart>
</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
/*标题头子组件*/
var cartTitle = {
props: ['uname'],/*用于从父组件传来值*/
template: `
<div class='title'>{{uname}}商品</div>
`
}
/*商品列表子组件*/
var cartList = {
props: ['list'],
template: `
<div>
<div v-bind:key='item.id' v-for='item in list' class="item"><!-- 遍历展示所有商品 -->
<img v-bind:src="item.img"/>
<div class="name">{{item.name}}</div>
<div class="change">
<a href="" v-on:click.prevent='sub(item.id)'>-</a><!-- 阻止a标签原有跳转,并在点击时,触发sub方法-->
<input type="text" class="num" v-on:blur='changeNum(item.id,$event)' v-bind:value='item.num' /><!-- 在失去焦点时触发changeNum方法,通过$event传递原有数据值-->
<a href="" v-on:click.prevent='add(item.id)'>+</a>
</div>
<div class="del" v-on:click='del(item.id)'>×</div><!-- 删除商品-->
</div>
</div>
`,
methods: {
sub: function (id) {
this.$emit('change_num', {/*子组件不直接对数据处理,通过向父组件传递change_num事件,让父组件处理数据*/
id: id,
type: 'sub'
})
},
add: function (id) {
this.$emit('change_num', {
id: id,
type: 'add'
})
},
changeNum: function (id, event) {
this.$emit('change_num', {/*子组件不直接对数据处理,通过向父组件传递change_num事件,让父组件处理数据,原来商品数量通过event.target.value传递*/
id: id,
num: event.target.value,
type: 'change'
});
},
del: function (id) {
this.$emit('cart-del', id);/*子组件不直接对数据处理,通过向父组件传递cart-del事件,让父组件处理数据*/
}
}
}
/*结算尾子组件*/
var cartTotal = {
props: ['list'],
template: `
<div class="total">
<span>总价:{{total}}</span>
<button>结算</button>
</div>
`,
computed: {/*计算方法*/
total: function () {
var t = 0;
this.list.forEach(item => {
t += item.price * item.num;
});
return t;
}
}
}
Vue.component('my-cart', {/*组件名称my-cart*/
/*数据data*/
data: function () {
return {
uname: 'ben',
list: [{
id: 1,
name: 'TCL彩电',
price: 1000,
num: 1,
img: 'img/a.jpg'
},
{
id: 2,
name: '机顶盒',
price: 1000,
num: 1,
img: 'img/b.jpg'
}, {
id: 3,
name: '海尔冰箱',
price: 1000,
num: 1,
img: 'img/c.jpg'
}, {
id: 4,
name: '小米手机',
price: 1000,
num: 1,
img: 'img/d.jpg'
}, {
id: 5,
name: 'PPTV电视',
price: 1000,
num: 2,
img: 'img/e.jpg'
}
]
}
},
/*包含三个子组件,分别是标题头,中间的商品列表,最后的结算尾*/
template: `
<div>
<cart-title v-bind:uname='uname'></cart-title>
<cart-list v-bind:list='list' v-on:cart-del='delCart($event)' v-on:change_num='changeNum($event)'></cart-list>
<cart-total v-bind:list='list'></cart-total>
</div>
`,
components: {
'cart-title': cartTitle,
'cart-list': cartList,
'cart-total': cartTotal
},
methods: {
/*改变商品数量的方法*/
changeNum: function (val) {
if (val.type == 'change') {
/*遍历找到商品与之所对应的id*/
this.list.some(item => {
if (item.id == val.id) {
item.num = val.num;
return true;
}
});
} else if (val.type == 'sub') {
this.list.some(item => {
if (item.id == val.id) {
item.num -= 1
}
})
} else {
this.list.some(item => {
if (item.id == val.id) {
item.num += 1
}
})
}
},
/*删除商品的方法*/
delCart: function (id) {
/*遍历找到id所对应的列表中的序号*/
var index = this.list.findIndex(item => {
return item.id == id;
});
/*删除列表中该序号的值*/
this.list.splice(index, 1);
}
}
});
var app = new Vue({
el: '#app',
data: {
}
});
</script>
</body>
</html>