作者:1031372720_eba8d5 | 来源:互联网 | 2023-09-16 10:55
一、渲染购物车列表页面新建srcviewsCart.vue获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据data(){return{cartList
一、渲染购物车列表页面
新建src/views/Cart.vue
获取cartList购物车列表数据就可以在页面中渲染出该用户的购物车列表数据
-
data(){
-
return {
-
cartList:[] // 购物车商品列表
-
}
-
},
-
mounted:function(){
-
this.init();
-
},
-
methods:{
-
init(){ // 初始化商品数据
-
axios.get('/users/cartList').then((response)=>{
-
let res = response.data;
-
this.cartList = res.result;
-
})
-
}
-
}
购物车接口:server/routes/users.js
-
// 查询当前用户的购物车数据
-
router.get('/cartList',function(req,res,next){
-
var userId = req.COOKIEs.userId;
-
User.findOne({userId:userId},function(err,doc){
-
if(err){
-
res.json({
-
status:'1',
-
msg:err.message,
-
result:''
-
});
-
}else{
-
if(doc){
-
res.json({
-
status:'0',
-
msg:'',
-
result:doc.cartList
-
})
-
}
-
}
-
})
-
})
建立路由src/router/index.js
-
import Cart from '@/views/Cart' // 购物车列表
-
export default new Router({
-
routes: [
-
{
-
path: '/cart', // 购物车列表路由
-
name: 'Cart',
-
component: Cart
-
}
-
-
]
-
})
二、购物车商品删除功能
购物车删除接口:server/routes/users.js
-
// 购物车删除功能
-
router.post('/cartDel',function(req,res,next){
-
var userId = req.COOKIEs.userId,productId = req.body.productId;
-
User.update({
-
userId:userId
-
},{
-
$pull:{
-
'cartList':{
-
'productId':productId
-
}
-
}
-
},function(err,doc){
-
if(err){
-
res.json({
-
status:'1',
-
msg:err.message,
-
result:''
-
});
-
}else{
-
res.json({
-
status:'0',
-
msg:'',
-
result:'suc'
-
});
-
}
-
})
-
});
src/views/Cart.vue
-
点击删除图标模态框出现(导入模态Modal.vue子组件)
-
-
Javascript:;"
class="
item-edit-btn" @click="
delCartConfirm(item.productId)">
-
="icon icon-del">
-
">
-
-
-
-
-
modalConfirm" @close="closeModal">
-
message
">你确认要删除此条数据吗?
-
btnGroup">
-
Javascript:;"
class="
btn btn--m" @click="
delCart">确认
-
Javascript:;"
class="
btn btn--m" @click="
modalConfirm = false">关闭
-
-
-
import Modal from '@/components/Modal.vue' // 模态框
-
export default {
-
data(){
-
return {
-
productId:'',
-
modalConfirm:false // 模态框是否显示
-
}
-
},
-
components:{
-
Modal
-
},
-
methods:{
-
delCartConfirm(productId){ // 点击删除图标
-
this.productId = productId;
-
this.modalConfirm = true; // 模态框显示
-
},
-
closeModal(){ // 关闭模态框
-
this.modalConfirm = false;
-
},
-
delCart(){ // 确认删除此商品
-
axios.post('/users/cartDel',{
-
productId:this.productId
-
}).then((response) => {
-
let res = response.data;
-
if(res.status = '0'){
-
this.modalConfirm = false; // 关闭模态框
-
this.init(); // 重新初始化购物车数据
-
}
-
})
-
}
-
}
-
}
**** 在这里发现一个bug,在商品列表页点击"加入购物车",购物车页面新添加的商品数量和总价格是未定义。mongoose添加属性问题
这是后端接口处理的问题,在server/routes/goods.js的加入到购物车接口中,是从mongodb的数据库dumall的goods表根据商品id获取对应数据,再对此商品数据添加productNum和checked属性,之后再插入到users表的购物车列表中的。
属性没有添加成功,在Goods模型中添加属性,要去models/goods.js的Schema添加这两个属性。
-
server/models/goods.js
-
// 定义一个Schema
-
var produtSchema = new Schema({
-
'productId':String,
-
'productName':String,
-
'salePrice':Number,
-
'productImage':String,
-
-
// 添加的属性
-
"checked":String,
-
"productNum":Number
-
})
-
module.exports = mongoose.model('good',produtSchema);
重新启动express(node server/bin/www)
三、购物车商品修改功能
商品加减和商品勾选
server/routes/users.js
-
//修改商品数量接口
-
router.post("/cartEdit",function(req,res,next){
-
var userId = req.COOKIEs.userId,
-
productId = req.body.productId,
-
productNum = req.body.productNum,
-
checked = req.body.checked;
-
User.update({ // 查询条件
-
"userId":userId,
-
"cartList.productId":productId
-
},{ // 修改的数据
-
"cartList.$.productNum":productNum,
-
"cartList.$.checked":checked
-
},function(err,doc){
-
if(err){
-
res.json({
-
status:'1',
-
msg:err.message,
-
result:''
-
});
-
}else{
-
res.json({
-
status:'0',
-
msg:'',
-
result:'suc'
-
});
-
}
-
});
-
})
src/views/Cart.vue
-
-
javascipt:;"
class="
checkbox-btn item-check-btn" v-bind:
class="
{'check':item.checked=='1'}" @click="
editCart('checked',item)">
-
="icon icon-ok">
-
">
-
-
-
-
class="
input-sub" @click="
editCart('minu',item)">-
-
class="
input-add" @click="
editCart('add',item)">
-
-
methods:{
-
editCart(flag,item){
-
if(flag == 'add'){ // 添加商品数量
-
item.productNum ;
-
}else if(flag = 'minu'){ // 减少商品数量
-
if(item.productNum <&#61; 1){
-
return;
-
}
-
item.productNum--;
-
}else{ // 商品控制选中
-
item.checked &#61; (item.checked&#61;&#61;&#39;1&#39;) ? &#39;0&#39; : &#39;1&#39;;
-
}
-
axios.post(&#39;/users/cartEdit&#39;,{
-
productId:item.productId,
-
productNum:item.productNum,
-
checked:item.checked
-
}).then((response)&#61;>{
-
let res &#61; response.data;
-
})
-
}
-
}
购物车全选和商品实时计算功能
server/routes/users.js
-
//全选和取消全选
-
router.post(&#39;/editCheckAll&#39;,function(req,res,next){
-
var userId &#61; req.COOKIEs.userId,
-
checkAll &#61; req.body.checkAll?&#39;1&#39;:&#39;0&#39;;
-
User.findOne({userId:userId},function(err,user){
-
if(err){
-
res.json({
-
status:&#39;1&#39;,
-
msg:err.message,
-
result:&#39;&#39;
-
});
-
}else{
-
if(user){
-
user.cartList.forEach((item)&#61;>{
-
item.checked &#61; checkAll;
-
})
-
user.save(function (err1,doc) {
-
if(err1){
-
res.json({
-
status:&#39;1&#39;,
-
msg:err1,message,
-
result:&#39;&#39;
-
});
-
}else{
-
res.json({
-
status:&#39;0&#39;,
-
msg:&#39;&#39;,
-
result:&#39;suc&#39;
-
});
-
}
-
})
-
}
-
}
-
})
-
})
src/views/Cart.vue
-
-
class&#61;"checkbox-btn item-check-btn" v-bind:class&#61;"{&#39;check&#39;:checkAllFlag}">
-
&#61;"icon icon-ok">
-
-
Select all
-
-
-
export default {
-
data(){
-
return {
-
checkAllFlag:false // 控制全选
-
}
-
},
-
methods:{
-
toggleCheckAll(){ // 全选和取消全选
-
this.checkAllFlag &#61; !this.checkAllFlag; // 取反
-
this.cartList.forEach((item)&#61;>{
-
item.checked &#61; this.checkAllFlag;
-
})
-
axios.post(&#39;/users/editCheckAll&#39;,{
-
checkAll:this.checkAllFlag
-
}).then((response)&#61;>{
-
let res &#61; response.data;
-
if(res.status&#61;&#61;&#39;0&#39;){
-
console.log("update suc");
-
}
-
})
-
}
-
}
-
}
这里出现一个问题&#xff0c;在点击select All全选之后&#xff0c;显示正常&#xff0c;但是刷新页面之后全选的图标没有显示全选&#xff0c;因为全选的信息没有存储到数据库保存&#xff0c;所以刷新之后就没有了。
【解决的办法】
用到了实时计算的computed功能&#xff0c;实时计算的是属性&#xff0c;只不过是函数的写法&#xff0c;data里面就不用在声明了。
src/views/Cart.vue
-
export default {
-
data(){
-
return {
-
// checkAllFlag:false // 控制全选
-
}
-
},
-
computed:{ // 实时计算的是属性&#xff0c;只不过是函数的写法&#xff0c;data里面就不用在声明了
-
checkAllFlag(){ // 是否全选属性
-
return this.checkedCount &#61;&#61; this.cartList.length; // 勾选的商品种数&#61;购物车商品列表的商品种数时&#xff0c;返回true代表全选。
-
},
-
checkedCount(){ // 获取已勾选的商品种数(几种商品已勾选)
-
var i &#61; 0;
-
this.cartList.forEach((item)&#61;>{
-
if(item.checked&#61;&#61;&#39;1&#39;)i ;
-
});
-
return i;
-
}
-
},
-
methods:{
-
toggleCheckAll(){ // 全选和取消全选
-
// this.checkAllFlag &#61; !this.checkAllFlag;
-
// 不能使用这种写法了&#xff0c;checkAllFlag是实时计算的属性&#xff0c;如果true取反变成false之后&#xff0c;还没来得及执行下面的所有商品取消勾选&#xff0c;就实时计算了检测到勾选的商品种数&#61;购物车商品列表的商品种数,就又变成全选了。
-
var flag &#61; !this.checkAllFlag; // 声明变量取代
-
this.cartList.forEach((item)&#61;>{
-
item.checked &#61; flag ?&#39;1&#39;:&#39;0&#39;;
-
})
-
axios.post(&#39;/users/editCheckAll&#39;,{
-
checkAll:flag
-
}).then((response)&#61;>{
-
let res &#61; response.data;
-
if(res.status&#61;&#61;&#39;0&#39;){
-
console.log("update suc");
-
}
-
})
-
}
-
}
-
}
页面一刷新就实时计算了
这里也要用到computed计算属性
-
class&#61;"item-total">
-
Item total: class&#61;"total-price">{{totalPrice}}
-
-
-
computed:{
-
totalPrice(){ // 总价格属性
-
var money &#61; 0;
-
this.cartList.forEach((item)&#61;>{
-
if(item.checked&#61;&#61;&#39;1&#39;){
-
money &#61; parseFloat(item.salePrice)*parseInt(item.productNum);
-
}
-
});
-
return money;
-
}
-
}
接下来要对价格进行格式化&#xff0c;vuex官网github有一个对购物车将格式化的函数https://github.com/vuejs/vuex/blob/dev/examples/shopping-cart/currency.js 可以拿过来对价格格式化&#xff0c;在src/util/currency.js
格式化要用到过滤器&#xff1a;可以在src/views/Cart.vue导入使用局部过滤器&#xff0c;也可以在main.js使用全局过滤器
-
class&#61;"total-price">{{totalPrice | currency(&#39;$&#39;)}}
-
-
// 局部过滤器
-
import {currency} from &#39;&#64;/util/currency.js&#39;
-
filters:{
-
currency:currency // currency.js传过来的本就是函数
-
},
-
-
// 全局过滤器
-
import {currency} from &#39;./util/currency&#39;
-
Vue.filter("currency",currency);
更多专业前端知识&#xff0c;请上
【猿2048】www.mk2048.com