地址管理:编辑地址 (编辑地址 和 添加地址使用的是同一个vue) 使用了 vant mounted处理data中数据相互依赖问题 ,Object.assign

658 阅读3分钟

前端->思路:

  1. 编辑地址 和 添加地址使用的是同一个vue组件页面,

    添加地址 在上一篇文章可以看到:juejin.cn/post/699595…

    注意:
    
    1.1 如何区分 编辑地址 和 添加地址? 绑定的click事件是一样的,通过传参来区分
    
     编辑地址 <li v-for="(item, index) in list" :key="index" @click="address(item)">
    
     新增地址 <div class="addAdderss" @click="address">
     
     然后跳转到页面:
     将参数以params形式传递过去,params传参的时候,页面路由要以name形式,否则无法跳转
     要使用这些地址信息来对页面进行编辑
     
      address(item) {
      if (item.id) {
        this.$router.push({ name: "AddAds", params: { data: item } });  // 跳转到 编辑地址页
      } else {
        this.$router.push({ name: "AddAds" }); // 跳转到添加地址页
      }
    },
    
    1.2 在跳转的页面中,接收传递过来的参数:注意接收方式:params
     showEditText: this.$route.params.data, // 编辑地址传递过来的信息
     
    1.2 接收到参数之后用来判断 头部展示 编辑 还是 新增文案 
      <div v-if="showEditText">编辑地址</div>
      <div v-else>添加地址</div>
      
    1.3  接收到参数之后用来判断 地址内容区域vant组件中 展示的是 编辑 还是新增 内容
     <!-- 编辑地址 -->
      <van-address-edit
        v-if="showEditText"
        :area-list="areaList"
        :address-info="AddressInfo"
        show-delete
        show-set-default
        show-search-result
        :search-result="searchResult"
        @save="onSaveEdit"
        @delete="onDelete"
        @change-detail="onChangeDetail"
      />
    
      <!-- 添加地址 -->
      <van-address-edit
        v-else
        :area-list="areaList"
        show-set-default
        show-search-result
        :search-result="searchResult"
        @save="onSave"
        @change-detail="onChangeDetail"
      />
    1.4 data中要加上:当页面是编辑地址的时候,要用来展示默认地址内容的,
     AddressInfo: {}, //这里 areaCode 地区编码,通过省市区选择获取(必填)
    1.5 将前端传递过来的参数 赋值给 1.4的AddressInfo对象,要先在mounted对数据进行处理后再赋值过去
    (采用方式二,一定要在mounted 中处理,因为data中的数据不能相互调用)
    
     mounted() {
        /* 将前端原有的地址信息通过mounted传递过来,  this.showEditText
           设置 默认地址选择,由于前端传递过来的isDefault 的值是0 或 1 
           但是前端展示的值是 true或false,
           所以要将数据取出来做判断之后 存进一个空对象中
          然后进行对象合并成一个对象 最后将数据传递给data中的AddressInfo
          这样才能让页面正常展示已填的信息
        */
    
    //  方式一
    /*
    let isDefault = this.showEditText.isDefault == 0 ? false : true;
    let datas = {};
    datas["isDefault"] = isDefault;
    let datasSources = Object.assign({ ...this.showEditText }, datas);
    this.AddressInfo = datasSources;
    console.log(this.AddressInfo);
    */
    
    // 方式二 
    /* 
     1 如果是 新增页面 前端是不会传 this.showEditText,三目运算要先判断这个是否存在,不存在就 null 否则报错 找不到这个数据
     2 将前端传递过来的数据,isDefault 默认地址字段根据传过来的数据是true或 false来展示
     3 前端重数据库读取到的 值是 1 或 0,所以根据判断 将值转为 true 或 false,
     */
     
    let isDefault = this.showEditText ? this.showEditText.isDefault == 0 ? false : true : "null";
    let datasSources = Object.assign({ ...this.showEditText }, { isDefault }); // 合并对象注意参数先后顺序
    this.AddressInfo = datasSources;
    },
    
  2. 发送编辑地址请求,编辑成功后 跳转到 我的地址页面

     注意:
     2.1 发送的数据:isDefault 默认传递的是 ture 或 false,为了更好的写进数据库 自己在发送请求之前,改成 10 --> content.isDefault = content.isDefault ? 1 : 0;
    
       // 编辑地址后 保存功能
     async onSaveEdit(content) {
       // 点击保存 将填写的内容传递给后端,后端来做数据库插入
       content.isDefault = content.isDefault ? 1 : 0;
       let res = await http.$axios({
         url: "/api/editAddress",
         method: "POST",
         headers: {
           token: true,
         },
         data: {
           ...content,
         },
       });
       if (res.success) Toast(res.msg);
       //   跳转到 我的地址页面
       this.$router.push("/path");
     },
    

前端完整代码:编辑地址

<template>
  <div class="addaddress">
    <header>
      <Header>
        <template #login>
          <div></div>
        </template>
        <template #middle>
          <div v-if="showEditText">编辑地址</div>
          <div v-else>添加地址</div>
        </template>
      </Header>
    </header>
    <section>
      <Section>
        <template #section>
          <!-- 编辑地址 -->
          <van-address-edit
            v-if="showEditText"
            :area-list="areaList"
            :address-info="AddressInfo"
            show-delete
            show-set-default
            show-search-result
            :search-result="searchResult"
            @save="onSaveEdit"
            @delete="onDelete"
            @change-detail="onChangeDetail"
          />

          <!-- 添加地址 -->
          <van-address-edit
            v-else
            :area-list="areaList"
            show-set-default
            show-search-result
            :search-result="searchResult"
            @save="onSave"
            @change-detail="onChangeDetail"
          />
        </template>
      </Section>
    </section>
    <Tabber></Tabber>
  </div>
</template>

<script>
import Tabber from "@/components/common/Tabbar.vue";
import Header from "@/components/my/Header.vue";
import Section from "@/components/my/Section.vue";
import { Toast } from "vant";
import http from "@/common/api/request.js";
export default {
  name: "AddAddress",
  components: {
    Section,
    Header,
    Tabber,
  },
  created() {
    this.datas();
  },

  mounted() {
    /* 将前端原有的地址信息通过mounted传递过来,  this.showEditText
       设置 默认地址选择,由于前端传递过来的isDefault 的值是0 或 1 
       但是前端展示的值是 true或false,
       所以要将数据取出来做判断之后 存进一个空对象中
      然后进行对象合并成一个对象 最后将数据传递给data中的AddressInfo
      这样才能让页面正常展示已填的信息
    */

    //  方式一
    /*
    let isDefault = this.showEditText.isDefault == 0 ? false : true;
    let datas = {};
    datas["isDefault"] = isDefault;
    let datasSources = Object.assign({ ...this.showEditText }, datas);
    this.AddressInfo = datasSources;
    console.log(this.AddressInfo);
    */
    // 方式二
    let isDefault = this.showEditText
      ? this.showEditText.isDefault == 0
        ? false
        : true
      : "null";
    let datasSources = Object.assign({ ...this.showEditText }, { isDefault });
    this.AddressInfo = datasSources;
  },
  data() {
    return {
      showEditText: this.$route.params.data, // 编辑地址传递过来的信息
      AddressInfo: {}, //这里 areaCode 地区编码,通过省市区选择获取(必填)
      areaList: {
        province_list: {
          110000: "北京市",
          120000: "天津市",
          440000: "广东省",
        },
        city_list: {
          110100: "北京市",
          120100: "天津市",
          440300: "深圳市",
        },
        county_list: {
          110101: "东城区",
          110102: "西城区",
          440306400498: "宝安区",
          // ....
        },
      },
      searchResult: [],
      setDefault: 0,
    };
  },
  methods: {
    datas() {
      console.log(this.AddressInfo, "45689789789798");
    },
    async onSave(content) {
      // 点击保存 将填写的内容传递给后端,后端来做数据库插入
      content.isDefault = content.isDefault ? 1 : 0;
      console.log(content, "fasongqingqiu ");
      let res = await http.$axios({
        url: "/api/addAddress",
        method: "POST",
        headers: {
          token: true,
        },
        data: {
          ...content,
        },
      });
      if (res.success) Toast(res.msg);
      // 跳转到 我的地址页面
      this.$router.push("/path");
    },

    onChangeDetail(val) {
      if (val) {
        this.searchResult = [
          {
            name: "黄龙万科中心",
            address: "杭州市西湖区",
          },
        ];
      }
    },

    // 编辑地址后 保存功能
    async onSaveEdit(content) {
      // 点击保存 将填写的内容传递给后端,后端来做数据库插入
      content.isDefault = content.isDefault ? 1 : 0;
      let res = await http.$axios({
        url: "/api/editAddress",
        method: "POST",
        headers: {
          token: true,
        },
        data: {
          ...content,
        },
      });
      if (res.success) Toast(res.msg);
      //   跳转到 我的地址页面
      this.$router.push("/path");
    },
  },
};
</script>
<style lang="less" scoped>
.addaddress {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: rgb(236, 230, 230);
}
section {
  flex: 1;
  overflow: hidden;
  ul li {
    height: 1.706667rem;
    background-color: #fff;
    div {
      height: 0.8rem;
    }
  }
  ::v-deep .van-button--danger {
    font-size: 0.426667rem;
    background-color: #13acf3;
    border: 1px solid #13acf3;
  }
}
</style>

后端思路

1.获取前端传递过来的参数:token

 注意:
 1.1 token 要解析,解析出来的token赋值为一个变量,然后判断token是否为null 如果为null 返回用户信息 让前端去做判断,跳转到登录页面
 1.2  通过解析出来的token获取到电话号码${tokenObj.tel} 去查询用户user表,保存id作为用户uid
 

2. 获取前端传递过来的地址信息,并解构出来需要的字段,将需要的字段信息通过sql更新到 数据库中

注意:
2.1  根据前端传递过来的uid查询path表 将这条地址查询出来 

2.2 将数据查出来之后,判断当前的数据默认地址isDefault是 1 还是 0,如果是不是 1 就直接更新当前这条数据,  如果isDefault是 1 先将其他 isDefault 改为 0 然后 更新这条数据
2.3 统一更新数据库的sql语句,然后直接使用
let updateQuery = `update path set name=?, tel=?, province=?, city =?, county=?, areaCode=?, isDefault=?, addressDetail=? where id=${id} and uid = ${uid}`

后端接口代码

 // 编辑地址更新数据库数据
router.post('/api/editAddress', function (req, res, next) {
  // 前端传递过来地址信息
  console.log(req.body, 'req.body');
  let {
    id,
    uid,
    name,
    tel,
    province,
    city,
    county,
    areaCode,
    isDefault,
    addressDetail
  } = req.body
  console.log(id, uid, name, tel, province, city, county, areaCode, isDefault, addressDetail, 'adfadsfadsfa');

  // 前端传递过来的token,解析token
  let tokens = req.headers.token;
  let tokenObj = jwt.decode(tokens) //结果 { tel: '18666554444', iat: 1628506659 }
  console.log(tokenObj.tel, "当前用户手机号");
  if (tokenObj == null) {
    res.send({
      data: {
        code: 400,
        success: false,
        msg: '请先登录'
      }
    })
  } else {
    // 根据token解析出来的手机号,来查询对应的用户表,查到对应的用户
    connection.query(`select * from user where tel ="${tokenObj.tel}"`, function (e, r) {
      if (r) {
        let uid = r[0].id
        // 更新数据库的sql语句
        let updateQuery = `update path set name=?, tel=?, province=?, city =?, county=?, areaCode=?, isDefault=?, addressDetail=? where id=${id} and uid = ${uid}`
        console.log(uid, "编辑");
        // 根据uid查询path表 将这条地址查询出来
        connection.query(`select * from path where id = ${id} and uid = ${uid}`, function (e, r) {
          if (r.length) {
            // 将数据查出来之后,判断当前的数据默认地址isDefault是 1 还是 0,如果是不是 1 就直接更新当前这条数据,
            if (isDefault != 1) {
              connection.query(updateQuery, [name, tel, province, city, county, areaCode, isDefault, addressDetail], function (e, r) {
                console.log(r, "r直接更新当前这条数据,");
                if (r) {
                  res.send({
                    data: {
                      code: 200,
                      success: true,
                      msg: '编辑地址保存地址成功00',
                    }
                  })
                }

              })
            } else {
              // 如果isDefault是 1 先将其他 isDefault 改为 0 然后 更新这条数据
              connection.query(`update path set isDefault = 0 where uid = ${uid} and isDefault = 1`, function (e, result) {
                console.log(result, "我是先将其他 isDefault 改为 0 然后 更新这条数据");
                if (result) {
                  connection.query(updateQuery, [name, tel, province, city, county, areaCode, isDefault, addressDetail], function (e, r) {
                    res.send({
                      data: {
                        code: 200,
                        success: true,
                        msg: '编辑地址保存地址成功11',
                      }
                    })
                  })
                }
              })
            }
          }
        })
      }
    })
  }
})


image.png