Vue 商城购物车 细节处理优化版 :组件化开发综合案例 (详细代码分析在底部)

需求:

在这里插入图片描述


案例展示:

{{item.name}}
×

`,
methods: {
changeNum: function(id, event) {
this.$emit(‘change-num’, {
id: id,
type: ‘change’,
num: event.target.value
})
},
//按+ -得到的数据也传递到changeNum
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: [‘lists’],
template: `

总价:{{total}}

`,
computed: {
//利用计算属性来计算总价 要有return值
total: function() {
//计算商品总价
var sum = 0;
this.lists.forEach(item => {
//foeEach遍历出数据
sum += item.price * item.num;
//总价=单价x数量
})
return sum;
}
},
}
Vue.component(‘my-cart’, {
data() {
return {
uname: ‘XXW’,
lists: [{
id: 1,
name: ‘TCL彩电’,
price: 1200,
num: 1,
img: ‘img/a.jpg’,
}, {
id: 2,
name: ‘机顶盒’,
price: 800,
num: 1,
img: ‘img/b.jpg’,
}, {
id: 3,
name: ‘海尔冰箱’,
price: 2200,
num: 1,
img: ‘img/c.jpg’,
}, {
id: 4,
name: ‘小米手机’,
price: 1799,
num: 1,
img: ‘img/d.jpg’,
}, {
id: 5,
name: ‘PPTV电视’,
price: 1888,
num: 1,
img: ‘img/e.jpg’,
}, ] }
},
template: `

`,
components: {
//第一局部组件 定义太多全局组件容易起冲突
‘cart-title’: CartTitle,
‘cart-list’: CartList,
‘cart-total’: CartTotal
},
methods: {
changeNum: function(val) {
var reg = /^[0-9]{1,5}$/; //正则匹配不能输入中文
//分三种情况:输入域变更,加号变更,减号变更
if (val.type == ‘change’) {
if (reg.test(val.num)) {
console.log(reg.test(val.num)); //true
console.log(typeof val.num); //隐式迭代 变成string型
//根据子组件传递过来的数据,跟新list中对应的数据
this.lists.some(item => {
if (item.id == val.id) {
if (item.num > 0) {
//输入框不能为负值
item.num = val.num;
} else {
item.num = 0;
}
//终止遍历
return true;
}
});
} else {
console.log(reg.test(val.num)); //false
this.lists.some(item => {
if (item.id == val.id) {
item.num = 0;
//终止遍历
return true;
}
});
}
} else if (val.type == ‘sub’) {
//减一操作
this.lists.some(item => {
//不能减到0以下
if (item.id == val.id) {
if (item.num >= 1) {
item.num = item.num * 1 – 1;
//我的想法是给item.num*1 这样就又转number类型 直接把item.num 写成 item.Number(num)没有用 显示undefined
} else {
item.num = 0;
}
//终止遍历
return true;
}

});
} else if (val.type == ‘add’) {
//加一操作
this.lists.some(item => {
if (item.id == val.id) {
item.num = item.num * 1 + 1;
//终止遍历
return true;
}
})
}
},
delCart: function(id) {
this.lists = this.lists.filter(function(item) { //把筛选后的结果重新赋值给books
return item.id != id //返回那些id 不相等的对象 形成一个新的数组
})
}
},
});

var vm = new Vue({
el: ‘#app’,
data: {}
})



js代码分析:

1. 局部定义的变量组件一定要放在全局component前面!!!

2.不能写成{{item.img}} !! 直接写item.img

3.利用computed计算属性要有返回值return

4.利用正则表达式匹配,让输入框只能输入数字,是中文直接归零。

注意!!!:正则表达式匹配后的num的数据类型发生了改变(隐式迭代)number=>string,导致后面的加减号按键是字符相加

在这里插入图片描述
在这里插入图片描述
解决方法

后面加减按键的增加减少的代码改成如下

//加
item.num = item.num * 1 - 1;
//减
item.num = item.num * 1 + 1;

我的想法是给 item.num*1 这样就又转number类型 直接把item.num 写成 item.Number(num)没有用 结果是undefined

5. (细节处理)减号按键的操作不能让他<0,利用条件判断。

6.删除按钮的两种写法

第一种:(分析看注释)

delCart: function(id) {
this.lists = this.lists.filter(function(item) { //把筛选后的结果重新赋值给books
return item.id != id //返回那些id 不相等的对象 形成一个新的数组
})
}

第二种(分析看注释)

delCart: function(id) {
// 根据id删除list中对应的数据
// 1、找到id所对应数据的索引
var index = this.list.findIndex(item => {
return item.id == id;
});
// 2、根据索引删除对应数据
this.list.splice(index, 1);
}


作者:Mr.xiaow

相关推荐

用jQuery实现抽奖程序

详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法

Vue实现Layui的集成方法步骤

详解vue-flickity的fullScreen功能实现