前段时间听说一段这样这样的话,如何你要快速在一个行业里习得工作的本领,那你的先掌握该领域最核心的20%的技能,根据二八定理,掌握这20%的技能知识你将可以解决该领域80%的问题。
我们都知道学习vue最经典最有代表性的demo就是购物车。今天终于静下心来和大家分享一下自己写的一个购物车的案例。
1.实现效果图如下所示
页面很简单,所有的功能列和展示都是放在一个简单的table里面
2.功能需求
a.商品数量列里面点击加减实现商品数量的加减,或者在输入框中直接输入的时候,金额和总金额也发生改变,
b.点击复选框选项实现单选 点击全选实现全选,点击取消全选实现取消全选,总金额也发生改变
c.点击删除实现删除功能,总金额也发生改变
3.整理代码如下
<template> <div id="app"> <router-view></router-view> <table border="1" width="100%" cellspacing="0" height="200px"> <tr> <th ></th> <th>商品名称</th> <th>商品单价</th> <th>商品数量</th> <th>金额</th> <th>操作</th> </tr> <tr v-for="(item,index) in cartlist" :key="item.id"> <td><input type="checkbox" @click="dainji(item,flag)" :checked="item.checked"></td> <td>{{item.title}}</td> <td>{{item.price| rounding}}</td> <td><button @click="changeNumber(item,false)">-</button><input type="text" :value="item.number" @change="change1($event,item)"><button @click="changeNumber(item,true)">+</button></td> <td>{{item.price*item.number|rounding}}</td> <td><el-button @click="deleteList(index)">删除</el-button></td> </tr> <tr> <td><button @click="chooseAll(cartlist,true)">全选</button></td> <td><button @click="chooseAll(cartlist,false)">取消全选</button></td> <td>总金额</td> <td>:</td> <td>{{total|rounding}}</td> <td><el-button @click="goPage">跳转1</el-button> <router-link to="/test"><el-button>跳转2</el-button></router-link></td> </tr> </table> </div> </template> <script> export default { name: 'App', data(){ return{ cartlist:[], flag:false, total:0, isShow:false } }, components:{ }, mounted(){ this.getGoodsList() }, compute:{ total(){ } }, filters: { rounding (value) { return parseInt(value).toFixed(2) } }, methods:{ getGoodsList(){ this.$http.post("/posts4").then(res => { console.log(res.data.posts); let cartlist1 =res.data.posts this.cartlist= cartlist1 }) }, change1(e,item){ item.number=e.target.value }, changeNumber(data,flag){ if(flag==true){ data.number+=1; this.computemoney() }else{ data.number-=1 this.computemoney() if(data.number<1){ data.number=1 } } }, dainji(item){ if(typeof item.checked=='undefined'){ this.$set(item,'checked',true) this.computemoney() console.log(item) }else{ console.log(item) item.checked=!item.checked this.computemoney() } }, chooseAll(data,flag){ data.forEach(item => { if(flag){ if(typeof item.checked=='undefined'){ this.$set(item,'checked',true) this.computemoney() }else{ if(item.checked==true){ return false }else{ item.checked=true this.computemoney() } } }else{ if(typeof item.checked=='undefined'){ this.$set(item,'checked',false) }else{ if(item.checked==true){ item.checked=false this.computemoney() }else{ return false } } } }); }, computemoney(){ this.total=0 this.cartlist.forEach((item)=>{ if(item.checked==true){ this.total+=item.price*item.number } }) }, deleteList(number){ console.log(number) // this.isShow=true this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { console.log(number) this.cartlist.splice(number,1) this.$message({ type: 'success', message: '删除成功!' }); this.computemoney() }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }, goPage(){ this.$router.push({name:'Dialog'}) } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
4.各个相应功能的实现源码
a.实现+ - 金额
页面
<td><button @click="changeNumber(item,false)">-</button>
<input type="text" :value="item.number" @change="change1($event,item)">
<button @click="changeNumber(item,true)">+</button></td>
方法
change1(e,item){
item.number=e.target.value
},
changeNumber(data,flag){
if(flag==true){
data.number+=1;
this.computemoney()
}else{
data.number-=1
this.computemoney()
if(data.number<1){
data.number=1
}
}
},
解析:由于加减两个按钮实现的都是一个业务逻辑,将item.number+或者减就可以,故而使用同一个方法通过设置flag的值分别是true or false 来在内部做判断实现数量的加减
重点不是这一块,重点是如何实现直接修改输入框值的改变从何改变item.number从而也能实现金额的改变,这一块主要是input里面的change方法通过e.target.value获取输入框的值,item.number=e.target.value最后赋给数量
b.实现单选、全选和取消全选
页面
<td><input type="checkbox" @click="dainji(item,flag)" :checked="item.checked"></td>
<td><button @click="chooseAll(cartlist,true)">全选</button></td>
<td><button @click="chooseAll(cartlist,false)">取消全选</button></td>
方法
dainji(item){
if(typeof item.checked=='undefined'){
this.$set(item,'checked',true)
this.computemoney()
console.log(item)
}else{
console.log(item)
item.checked=!item.checked
this.computemoney()
}
},
chooseAll(data,flag){
data.forEach(item => {
if(flag){
if(typeof item.checked=='undefined'){
this.$set(item,'checked',true)
this.computemoney()
}else{
if(item.checked==true){
return false
}else{
item.checked=true
this.computemoney()
}
}
}else{
if(typeof item.checked=='undefined'){
this.$set(item,'checked',false)
}else{
if(item.checked==true){
item.checked=false
this.computemoney()
}else{
return false
}
}
}
});
},
computemoney(){
this.total=0
this.cartlist.forEach((item)=>{
if(item.checked==true){
this.total+=item.price*item.number
}
})
},
解析思路:
第一步:实现复选框单选 通过动态绑定:checked="item.checked" 实现点击被选的同时将这个被选的属性标志同时set进item对象里面,由于后台数据里面是没有是否被选中的属性的,所以当一次点击某一个复选框的时候是需要自己添加进去this.$set(item,'checked',true),这样一个操作不仅使得复选框被选,同时还往item这个对象里面插了一个属性和对应值。那么问题来了我每次点击的时候都需要插入吗,于是在设置这个值之前需要判断一下该item里面是否有这个属性,if(typeof item.checked=='undefined'){}这就是判断的代码,当我们在触发复选框的时候如果我们之前点击过往里面插过(设置过checked)我们只需要将该属性取反即可,否则就set,
if(typeof item.checked=='undefined'){ this.$set(item,'checked',true) this.computemoney() console.log(item) }else{ console.log(item) item.checked=!item.checked this.computemoney() } },
相信你现在可以看懂这一步的逻辑了吧!你们肯定会想我为什么要这么做呢?先不急,咋们到现在只是说了单选,还有一个全选
第二步:实现了刚刚的功能这一步其实不难,同样我们在点击全选的时候我们要做的事情就是让每一个item.checked=true,那么我们需要做两个判断,第一层判断是否函数checked这个属性,
第二个判断当前checked属性是否为true如果没有则将列表里遍历到的该item添加该属性,否则就直接修改
if(typeof item.checked=='undefined'){ this.$set(item,'checked',true) this.computemoney() }else{ if(item.checked==true){ return false }else{ item.checked=true this.computemoney() } }
接着就是取消全选了,业务逻辑完全一样就是需要将每一个checked设置为false即可,故而同样的处理,设置一个flag,true的时候全选,false取消全选
chooseAll(data,flag){ data.forEach(item => { if(flag){ if(typeof item.checked=='undefined'){ this.$set(item,'checked',true) this.computemoney() }else{ if(item.checked==true){ return false }else{ item.checked=true this.computemoney() } } }else{ if(typeof item.checked=='undefined'){ this.$set(item,'checked',false) }else{ if(item.checked==true){ item.checked=false this.computemoney() }else{ return false } } } }); },
到现在我们实现了页面的全选和取消全选功能,接着就是计算总金额了
第三步:实现总金额 思路很简单遍历列表选择出被选中的计算并叠加
computemoney(){
this.total=0
this.cartlist.forEach((item)=>{
if(item.checked==true){
this.total+=item.price*item.number
}
})
},
第四步 在所有被选中的item里进行
item.price*item.number,在被选中,且数量增加的地方也调用这个方法,这个地方写的不是很好,相信你们能够有更好的实现方法。我这里就是在需要调用该方法的地方都调用了一下。
最后一步:实现删除功能 这个很简单麻将index传进方法里面
deleteList(number){ console.log(number) // this.isShow=true this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { console.log(number) this.cartlist.splice(number,1) this.$message({ type: 'success', message: '删除成功!' }); this.computemoney() }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); }
this.cartlist.splice(number,1) 这是实现删除的关键核心代码。
项目到这就已经完成啦啦啦啦,不知道屏幕前的你们是否理解了呢?如果你有更好的实现方式欢迎你们和我一起交流咋们一起成长吧!
希望本文对你们有所帮助,点个赞再走吧,希望得到鼓励呢!