vant H5 地址编辑框

本文详细描述了如何在vantH5框架中使用自定义模板和组件实现地址编辑框,包括地区选择功能的动态加载和验证,以及与Vue.js方法的交互过程。
摘要由CSDN通过智能技术生成

vant H5 地址编辑框

效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上代码:

<!-- 地区选择 -->
<template>
  <div class="page-content">
    <van-field
      v-model="formNationaAll"
      is-link
      readonly
      required
      name="国家/地区"
      label="国家/地区"
      placeholder="请选择"
      :rules="[{ required: true, message: '请选择' }]"
      @click="
        opendistrictPopup({
          nation: formNation,
          province: formProvince,
          city: formCity,
          area: formArea,
          detailedAddress: formDetailedAddress,
        })
      "
    >
      <template #input>
        <span>{{ formNationaAll }}</span>
        <span class="color-warn" v-show="showPlaceholderFun(formNationaAll)"
          >请选择</span
        >
      </template>
    </van-field>
    <van-field
      v-model="formDetailedAddress"
      required
      readonly
      name="详细地址"
      label="详细地址"
      placeholder="请输入"
      :rules="[{ required: true, message: '请输入详细地址到门牌号' }]"
      @click="
        opendistrictPopup({
          nation: formNation,
          province: formProvince,
          city: formCity,
          area: formArea,
          detailedAddress: formDetailedAddress,
        })
      "
    ></van-field>
    <van-popup
      v-model="districtPopup"
      round
      position="top"
      :close-on-click-overlay="false"
      :style="{ height: '30%' }"
    >
      <van-dropdown-menu>
        <van-dropdown-item
          v-model="nation"
          :options="nationList"
          @change="changenation"
        >
          <template #title
            ><span v-if="showPlaceholderFun(nation)">国家</span
            ><span v-else>{{ nationName }}</span></template
          ></van-dropdown-item
        >
        <van-dropdown-item
          v-model="province"
          :options="provinceList"
          @change="changeprovince"
          :disabled="showPlaceholderFun(nation)"
        >
          <template #title
            ><span v-if="showPlaceholderFun(province)">省份</span
            ><span v-else>{{ provinceName }}</span></template
          ></van-dropdown-item
        >
        <van-dropdown-item
          v-model="city"
          :options="cityList"
          @change="changecity"
          :disabled="showPlaceholderFun(province)"
        >
          <template #title
            ><span v-if="showPlaceholderFun(city)">城市</span
            ><span v-else>{{ cityName }}</span></template
          ></van-dropdown-item
        >
        <van-dropdown-item
          v-model="area"
          :options="areaList"
          @change="changearea"
          :disabled="showPlaceholderFun(city)"
        >
          <template #title
            ><span v-if="showPlaceholderFun(area)">区县</span
            ><span v-else>{{ areaName }}</span></template
          ></van-dropdown-item
        >
      </van-dropdown-menu>
      <van-field
        v-model.trim="detailedAddress"
        reareaired
        name="详细地址"
        label="详细地址"
        placeholder="请输入详细地址到门牌号"
        rows="2"
        type="textarea"
      ></van-field>
      <div class="btns">
        <van-button class="infobtn" round @click="closePopup" v-preventReClick
          >取消</van-button
        >
        <van-button type="primary" round @click="confirmPopup" v-preventReClick
          >确定</van-button
        >
      </div>
    </van-popup>
  </div>
</template>
<script>
import { ProvincesAndMunicipalities } from "@/apis/insus/insusHome";
import { Notify } from "vant";
export default {
  name: "DistrictSelect",
  data() {
    return {
      // 表单字段
      formNationaAll: "",
      formNation: "",
      formProvince: "",
      formCity: "",
      formArea: "",
      formDetailedAddress: "",

      // 组件字段
      districtPopup: false,
      nation: "",
      nationName: "",
      nationList: [{ text: "中国", value: "CHN", code: "CHN" }],
      province: "",
      provinceName: "",
      provinceList: [],
      city: "",
      cityName: "",
      cityList: [],
      area: "",
      areaName: "",
      areaList: [],
      detailedAddress: "",
    };
  },

  methods: {
    //打开地区
    async opendistrictPopup(obj) {
      if (obj && obj.nation) {
        this.nation = obj.nation;
        await this.changenation();
      }
      this.provinceList = await this.getProvincesAndMunicipalitiesFun(0);
      if (obj && obj.province) {
        this.province = obj.province;
        await this.changeprovince();
      }
      if (obj && obj.city) {
        this.city = obj.city;
        await this.changecity();
      }
      if (obj && obj.area) {
        this.area = obj.area;
        await this.changearea();
      }
      if (obj && obj.detailedAddress) {
        this.detailedAddress = obj.detailedAddress;
      }
      this.districtPopup = true;
    },
    // 获取省市区
    async getProvincesAndMunicipalitiesFun(ins) {
      let res = await ProvincesAndMunicipalities({ parentId: ins });
      if (res && res.cityList && res.cityList.length > 0) {
        return res.cityList.map((item) => {
          return { text: item.name, value: item.code, ...item };
        });
      } else {
        return [];
      }
    },
    showPlaceholderFun(val) {
      if (!!val) {
        return false;
      } else {
        if (val === 0) {
          return false;
        } else {
          return true;
        }
      }
    },
    // 选择国家
    async changenation() {
      let obj = await this.findByCode(this.nationList, this.nation);
      this.nationName = obj.text;
    },
    // 选择省份
    async changeprovince() {
      let obj = await this.findByCode(this.provinceList, this.province);
      this.provinceName = obj.text;
      if (obj.code === this.province) {
        this.cityList = await this.getProvincesAndMunicipalitiesFun(obj.id);
        this.city = "";
        this.area = "";
      }
    },
    // 选择市
    async changecity() {
      let obj = await this.findByCode(this.cityList, this.city);
      this.cityName = obj.text;
      if (obj.code === this.city) {
        this.areaList = await this.getProvincesAndMunicipalitiesFun(obj.id);
        this.area = "";
      }
    },
    // 选择区
    async changearea() {
      let obj = await this.findByCode(this.areaList, this.area);
      this.areaName = obj.text;
    },

    findByCode(tree, code) {
      for (let i = 0; i < tree.length; i++) {
        if (tree[i].code === code) {
          return tree[i];
        }
      }
      return null;
    },
    confirmPopup() {
      if (
        this.showPlaceholderFun(this.nation) ||
        this.showPlaceholderFun(this.province) ||
        this.showPlaceholderFun(this.city) ||
        this.showPlaceholderFun(this.area) ||
        this.showPlaceholderFun(this.detailedAddress)
      ) {
        Notify({
          message: "请填写完所有信息!",
          duration: 2000,
          background: "#ed3e48",
        });
      } else {
        this.formNationaAll = `${this.nationName}/${this.provinceName}/${this.cityName}/${this.areaName}`; //国家地区
        this.formNation = this.nation;
        this.formProvince = this.province;
        this.formCity = this.city;
        this.formArea = this.area;
        this.formDetailedAddress = this.detailedAddress;
        this.$emit("confirmDistrict", {
          formNationaAll: this.formNationaAll,
          nation: this.nation,
          nationName: this.nationName,
          province: this.province,
          provinceName: this.provinceName,
          city: this.city,
          cityName: this.cityName,
          area: this.area,
          areaName: this.areaName,
          detailedAddress: this.detailedAddress,
        });
        this.closePopup();
      }
    },
    closePopup() {
      this.nation = "";
      this.nationName = "";
      this.province = "";
      this.provinceName = "";
      this.city = "";
      this.cityName = "";
      this.area = "";
      this.areaName = "";
      this.detailedAddress = "";
      this.districtPopup = false;
    },
  },
  mounted() {},
  created() {},
};
</script>

<style scoped lang="less">
.page-content {
  .van-popup {
    .btns {
      display: flex;
      align-items: center;
      justify-content: space-around;
      margin-top: @margin-32;

      :deep(.van-button) {
        width: 40%;
      }

      .van-button--normal {
        height: 68px;
      }

      .infobtn {
        background-color: @-color-fff;
        border: 1px solid @-color-primary;
        color: @-color-primary;
      }
    }
  }

  :deep(.van-dropdown-item__content) {
    max-height: 100%;
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值