地址页面:
1、地址列表渲染
首先在这个页面中请求用户的地址列表数据,请求后在前端进行渲染。
前端代码:
mounted(){
this.init();
},
methods:{
init(){
axios.get('users/addressList').then((response)=>{
let res=response.data;
this.addressList=res.result;
this.selectedAddrId=this.addressList[0].addressId;
})
// console.log(this)
//为什么在这打不出addressList?????因为异步
// console.log(this.addressList)
},
后端代码:
router.get('/addressList',(req,res,next)=>{
let userId=req.cookies.userId;
User.findOne({userId:userId},(err,doc)=>{
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
res.json({
status:'0',
msg:'',
result:doc.addressList
})
}
})
})
在页面渲染时,有一个功能需要实现,默认显示三个地址,点击more展现所有地址列表,点击收回。这就要在li标签中的v-for=“item in addressList”将adderList改变为addressListFilter,然后在computed中注册该数据并实时监听改变.limit初始值为3,点击loadMore时将limit设为列表长度。
computed:{
addressListFilter(){
return this.addressList.slice(0,this.limit);
}
},
列表切换功能在li标签上点击将这个index复制给checkIndex,而且在li标签上用class=‘open’来控制选中状态。
<li v-for="(item,index) in addressListFilter" :class="{'check':checkIndex==index}" @click="checkIndex=index; selectedAddrId=item.addressId">
2、设置默认功能实现
<div class="addr-opration addr-set-default">
<a href="javascript:;" class="addr-set-default-btn" v-if="!item.isDefault" @click="setDefault(item.addressId)"><i>Set default</i></a>
</div>
<div class="addr-opration addr-default" v-if="item.isDefault">Default address</div>
通过 v-if="item.isDefault"和v-if="!item.isDefault"来控制默认地址和设置默认的显示,如果点击设置默认,将这个item的addressId传给setDefault参数。返回结果后遍历列表,将如果等于传进来的addressId就将isDefault设置为true,反之为false,来控制地址列表中的显示。
setDefault(addressId){
axios.post('/users/setDefault',{
addressId:addressId
}).then((response)=>{
this.addressList.forEach((item)=>{
if(item.addressId==addressId){
item.isDefault=true;
}else{
item.isDefault=false;
}
})
})
},
在后台也需要将isDefault的值进行同步。注意一点,在找到addressId并更改其isDefault后,要将这个item变成这个列表数组的第一个值,这样下次进来这个页面他就在第一个显示了。
router.post('/setDefault',(req,res,next)=>{
let userId=req.cookies.userId;
let addressId=req.body.addressId;
User.findOne({userId:userId},(err,doc)=>{
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
doc.addressList.forEach((item,index)=>{
if(item.addressId==addressId){
item.isDefault=true;
doc.addressList.splice(index,1);
doc.addressList.unshift(item);
}else{
item.isDefault=false;
}
})
doc.save((err1,doc1)=>{
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
res.json({
status:'0',
msg:'',
result:''
})
}
})
}
})
})
3、删除功能实现
点击删除图标后,将此地址的addressId传给delAdress函数。delAdress函数中将addreId传给data中定义的变量addressId,并将确认删除的模态框弹出来。点击模态框的确认删除按钮后,将调用delConfirm函数,在这个函数中向后台发出post请求,传递addressId这个参数,以便后台查找数据,删除后将模态框关闭,并重新渲染页面。
<a href="javascript:;" class="addr-del-btn" @click="delAdress(item.addressId)">
delAdress(addressId){
this.addressId=addressId;
this.mdDel=true;
},
delConfirm(){
axios.post('/users/delAdress',{
addressId:this.addressId
}).then((response)=>{
let res=response.data;
this.mdDel=false;
this.init();
})
}
},
后台删除数据:
通过update和$pull来删除数据。
router.post('/delAdress',(req,res,next)=>{
let userId=req.cookies.userId;
let addressId=req.body.addressId;
User.update({userId:userId},{$pull:{'addressList':{'addressId':addressId}}},(err,doc)=>{
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
res.json({
status:'0',
msg:'删除成功',
result:'suc'
})
}
})
})
4、点击next给下一个页面传递选中的addressId的参数,直接传到url中。
<router-link class="btn btn--m btn--red" :to="{path:'orderConfirm',query:{'addressId':selectedAddrId}}">Next</router-link>
这个selectedAddrId默认值是列表第一个的id,点击后,将其改变
<li v-for="(item,index) in addressListFilter" :class="{'check':checkIndex==index}" @click="checkIndex=index; selectedAddrId=item.addressId">