本文已参与「新人创作礼」活动,一起开启掘金创作之路。
购物车案例——实现组件更新数据功能【下】
- 子组件通过一个标识符来标记对应的用户点击
+、-或者输入框输入的内容; - 父组件拿到标识符更新对应的组件;
html 代码结构
<div id="app">
<div class="container">
<!-- 把组件渲染到页面上 -->
<my-cart></my-cart>
</div>
</div>
js 代码结构
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
code in here
</script>
1、实现组件更新数据功能【下】
1.1 +、- 按钮绑定事件
var CartTitle = {
props: ['uname'],
template: `
<div class="title">{{uname}}的商品</div>
`
}
var CartList = {
props: ['list'],
template: `
<div>
<div :key='item.id' v-for='item in list' class="item">
<img :src="item.img"/>
<div class="name">{{item.name}}</div>
<div class="change">
# 1. + - 按钮绑定事件
<a href="" @click.prevent='sub(item.id)'>-</a>
<input type="text" class="num" :value='item.num' @blur='changeNum(item.id, $event)'/>
<a href="" @click.prevent='add(item.id)'>+</a>
</div>
<div class="del" @click='del(item.id)'>×</div>
</div>
</div>
`,
1.2 数量的增加和减少通过父组件来计算
- 每次都是
加1和减1不需要传递数量。- 父组件需要一个类型来判断 是
加1还是减1,以及是输入框输入的数据。我们通过type标识符来标记不同的操作。
methods: {
changeNum: function(id, event){
this.$emit('change-num', {
id: id,
type: 'change',
num: event.target.value
});
},
sub: function(id){
this.$emit('change-num', {
id: id,
type: 'sub'
});
},
add: function(id){
this.$emit('change-num', {
id: id,
type: 'add'
});
},
del: function(id){
// 把id传递给父组件
this.$emit('cart-del', id);
}
}
}
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',{
data: function() {
return {
uname: '张三',
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'
}]
}
},
1.3 父组件通过事件监听,接收子组件的数据。
template: `
<div class='cart'>
<cart-title :uname='uname'></cart-title>
<cart-list
:list='list'
@change-num='changeNum($event)'
@cart-del='delCart($event)'></cart-list>
<cart-total :list='list'></cart-total>
</div>
`,
components: {
'cart-title': CartTitle,
'cart-list': CartList,
'cart-total': CartTotal
},
1.4 分为三种情况:输入框变更、加号变更、减号变更
根据子组件传递过来的数据,跟新list中对应的数据。
methods: {
changeNum: function(val) {
if(val.type=='change') {
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;
// 终止遍历
return true;
}
});
}else if(val.type=='add'){
// 加一操作
this.list.some(item=>{
if(item.id == val.id) {
item.num += 1;
// 终止遍历
return true;
}
});
}
}
}
});
var vm = new Vue({
el: '#app',
data: {
}
});