地址列表渲染实战

定义路由src/ router/index.js/

{
  path: '/address',
  name: 'Address',
  component:Address
},

导入组件

import Address from '@/views/Address'

一、地址列表渲染

 

购物车列表页中点击checkout结账,若已勾选的商品为0,则不可以点击。

src/views/Cart.vue

  1. <a class="btn btn--red" v-bind:class="{'btn--dis':checkedCount==0}" @click="checkOut">Checkout</a>

  2.  

  3. methods:{

  4.     checkOut(){ // 结账

  5.         if(this.checkedCount>0){ // 已勾选的商品种数>0时才可以跳转到地址列表页

  6.             this.$router.push( // 跳转到地址列表页

  7.                 {path:"/address"}

  8.             );

  9.         }

  10.     }

  11. }

 

未勾选时状态:

勾选时状态:

新建地址列表组件src/views/Address.vue,添加路由配置src/router/index.js

  1. import Address from '@/views/Address' // 地址列表

  2. export default new Router({

  3.   routes: [

  4.     {

  5.       path: '/address', // 地址列表路由

  6.       name: 'Address',

  7.       component: Address

  8.     }

  9.   ]

  10. })

 

渲染地址列表

地址列表后端接口:server/routes/users.js

  1. // 查询用户地址接口

  2. router.get("/addressList",function(req,res,next){

  3.     var userId = req.cookies.userId;

  4.     User.findOne({userId:userId},function(err,doc){

  5.         if(err){

  6.             res.json({

  7.                 status:'1',

  8.                 msg:err.message,

  9.                 result:''

  10.             })

  11.         }else{

  12.             res.json({

  13.                 status:'0',

  14.                 msg:'',

  15.                 result:doc.addressList

  16.             })

  17.         }

  18.     })

  19. })

 

地址列表前端调用:src/views/Address.vue

  1. <li v-for="item in addressList">

  2.     <dl>

  3.         <dt>{{item.userName}}</dt>

  4.         <dd class="address">{{item.streetName}}</dd>

  5.         <dd class="tel">{{item.tel}}</dd>

  6.     </dl>

  7.     <div class="addr-opration addr-del">

  8.         <a href="javascript:;" class="addr-del-btn">

  9.             <svg class="icon icon-del"><use xlink:href="#icon-del"></use></svg>

  10.         </a>

  11.     </div>

  12.     <div class="addr-opration addr-set-default">

  13.         <a href="javascript:;" class="addr-set-default-btn"><i>Set default</i></a>

  14.     </div>

  15.     <div class="addr-opration addr-default">Default address</div>

  16. </li>

  17. export default {

  18.     data(){

  19.         return {

  20.           addressList:[] // 地址列表

  21.         }

  22.     },

  23.     mounted(){

  24.       this.init();

  25.     },

  26.     methods:{

  27.       init(){

  28.         axios.get('/users/addressList').then((response) => {

  29.           let res = response.data;

  30.           this.addressList = res.result;

  31.  

  32.         })

  33.       }

  34.     }

  35. }

二、地址列表切换和展开

限制地址显示3个

用计算属性computed对地址列表数据进行处理

  1. <li v-for="item in addressListFilter">

  2.  

  3. export default {

  4.     data(){

  5.         return {

  6.           addressList:[], // 地址列表

  7.           limit:3 // 限制默认显示3个地址

  8.         }

  9.     },

  10.     computed:{

  11.       addressListFilter(){

  12.         return this.addressList.slice(0,this.limit);

  13.       }

  14.     }

  15. }

 

地址展开与收起

展开与收起控制的是显示地址的个数limit,同时图标发生变化

  1. <a class="addr-more-btn up-down-btn" href="javascript:;" @click="expand" v-bind:class="{'open':limit>3}">

  2.   more

  3.   <i class="i-up-down">

  4.     <i class="i-up-down-l"></i>

  5.     <i class="i-up-down-r"></i>

  6.   </i>

  7. </a>

  8. export default{

  9.     expand(){ // 点击more更多

  10.         if(this.limit ==3){

  11.           this.limit = this.addressList.length;

  12.         }else{

  13.           this.limit =3;

  14.         }

  15.     }

  16. }

 


地址选中切换

  1. 定义一个地址选中的索引数据checkIndex,当checkIndex等于所在li索引时,类名check加上;点击地址的时候将点击的li索引赋值给checkIndex。
    <li v-for="(item,index) in addressListFilter" v-bind:class="{'check':checkIndex == index}" @click="checkIndex=index"></li>

  2.  

  3. export default {

  4.     data(){

  5.         return {

  6.           checkIndex:0 // 选中的地址索引

  7.         }

  8.     }

  9. }

 

三、设置默认地址

server/models/users.js 先补充地址列表addressList的数据模型

  1. "addressList":[

  2.     {

  3.         "addressId": String,

  4.         "userName": String,

  5.         "streetName": String,

  6.         "postCode": Number,

  7.         "tel": Number,

  8.         "isDefault": Boolean

  9.     }

  10. ]

 

server/routes/users.js设置默认地址接口,前端传要设置的地址的addressId给后端,后端设置isDefault的值

  1. //设置默认地址接口

  2. router.post("/setDefault", function (req,res,next) {

  3.   var userId = req.cookies.userId,

  4.       addressId = req.body.addressId;

  5.   if(!addressId){

  6.     res.json({

  7.       status:'1003',

  8.       msg:'addressId is null',

  9.       result:''

  10.     });

  11.   }else{

  12.     User.findOne({userId:userId}, function (err,doc) {

  13.       if(err){

  14.         res.json({

  15.           status:'1',

  16.           msg:err.message,

  17.           result:''

  18.         });

  19.       }else{

  20.         var addressList = doc.addressList;

  21.         addressList.forEach((item)=>{

  22.           if(item.addressId ==addressId){

  23.              item.isDefault = true;

  24.           }else{

  25.             item.isDefault = false;

  26.           }

  27.         });

  28.  

  29.         doc.save(function (err1,doc1) {

  30.           if(err){

  31.             res.json({

  32.               status:'1',

  33.               msg:err.message,

  34.               result:''

  35.             });

  36.           }else{

  37.               res.json({

  38.                 status:'0',

  39.                 msg:'',

  40.                 result:''

  41.               });

  42.           }

  43.         })

  44.       }

  45.     });

  46.   }

  47. });

 

src/views/Address.vue前端

  1. <div class="addr-opration addr-set-default">

  2.     <a href="javascript:;" class="addr-set-default-btn" v-if="!item.isDefault" @click="setDefault(item.addressId)"><i>Set default</i></a>

  3. </div>

  4. <div class="addr-opration addr-default" v-if="item.isDefault">Default address</div>

  5.  

  6. methods:{

  7.     setDefault(addressId){ // 设置默认地址

  8.         axios.post('/users/setDefault',{

  9.           addressId:addressId

  10.         }).then((response)=>{

  11.           let res = response.data;

  12.           if(res.status=='0'){

  13.             console.log("set default");

  14.             this.init(); // 重新渲染地址列表

  15.           }

  16.         })

  17.       }

  18. }

 

四、地址删除功能

server/routes/users.js后端删除地址接口

  1. //删除地址接口

  2. router.post("/delAddress", function (req,res,next) {

  3.   var userId = req.cookies.userId,addressId = req.body.addressId;

  4.   User.update({

  5.     userId:userId

  6.   },{

  7.     $pull:{

  8.       'addressList':{

  9.         'addressId':addressId

  10.       }

  11.     }

  12.   }, function (err,doc) {

  13.       if(err){

  14.         res.json({

  15.             status:'1',

  16.             msg:err.message,

  17.             result:''

  18.         });

  19.       }else{

  20.         res.json({

  21.           status:'0',

  22.           msg:'',

  23.           result:''

  24.         });

  25.       }

  26.   });

  27. });

 

点击删除图标会出现一个模态框,点击模态框的确定按钮,发送要删除的地址的id给后端,请求删除,然后重新渲染地址列表,删除的数据不会再出现。

src/views/Address.vue

  1. <!--删除图标-->

  2. <a href="javascript:;" class="addr-del-btn" @click="delAddressConfirm(item.addressId)">

  3.     <svg class="icon icon-del"><use xlink:href="#icon-del"></use></svg>

  4. </a>

  5.  

  6. <!-- 模态框 -->

  7. <modal :mdShow="isMdShow" @close="closeModal">

  8.     <p slot="message">

  9.         您是否确认要删除此地址?

  10.     </p>

  11.     <div slot="btnGroup">

  12.         <a class="btn btn--m" href="javascript:;" @click="delAddress">确认</a>

  13.         <a class="btn btn--m btn--red" href="javascript:;" @click="isMdShow=false">取消</a>

  14.     </div>

  15. </modal>

  16. export default {

  17.     data(){

  18.         return {

  19.           isMdShow:false, // 模态框的显示设置

  20.           addressId:'' // 地址id的存储,用于请求传参

  21.         }

  22.     }

  23.     methods:{

  24.       closeModal(){ // 关闭模态窗

  25.         this.isMdShow = false;

  26.       },

  27.       delAddressConfirm(addressId){ // 点击删除图标,模态框出现

  28.         this.isMdShow = true;

  29.         this.addressId = addressId; // 地址id赋值

  30.       },

  31.       delAddress(){

  32.         axios.post("/users/delAddress",{

  33.           addressId:this.addressId // 传参

  34.         }).then((response)=>{

  35.             let res = response.data;

  36.             if(res.status=="0"){

  37.               console.log("del suc");

  38.               this.isMdShow = false; // 告诉模态框组件,设置模态框消失

  39.               this.init(); // 重新渲染地址

  40.             }

  41.         })

  42.       }

  43.     }

  44. }

 



点击Next跳转到订单确认页面

跳转要传选择的地址id传过去

src/views/Address.vue

  1. <!--选择地址的时候将地址id赋值给selectedAddrId-->

  2. <li v-for="(item,index) in addressListFilter" v-bind:class="{'check':checkIndex == index}" @click="checkIndex=index;selectedAddrId=item.addressId"></li>

  3.  

  4. <!--动态跳转,传参传入地址id-->

  5. <router-link class="btn btn--m btn--red" v-bind:to="{path:'/orderConfirm',query:{'addressId':selectedAddrId}}">Next</router-link>

  6.  

  7. export default {

  8.     data(){

  9.         return {

  10.           selectedAddrId:'' // 选中的地址id存储,用于点击Next跳转到订单确认页面传参

  11.         }

  12.     }

  13. }

 

点击Next跳转,跳转到订单确认页面,url带了选择的地址id参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值