• Vue nodejs商城-地址模块


    一、地址列表渲染

    购物车列表页中点击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. }

    二、地址列表切换和展开

    限制地址显示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参数

  • 相关阅读:
    使用express+mongoDB搭建多人博客 学习(6)发表文章
    [译]Understanding ECMAScript6 对象
    select的type属性
    jQuery addClass() 源码解读
    jQuery val()方法及valHooks源码解读
    mpvue使用scroll-view实现图片横向滑动
    mpvue图片轮播遇到的问题
    mpvue小程序图片404
    js截取字符串的后几位数
    jQuery WeUI实现分页功能
  • 原文地址:https://www.cnblogs.com/wangyawei/p/9236797.html
Copyright © 2020-2023  润新知