VUE--全国区域选择---根据输入的地址自动获取区域信息

HTML部分

<div class="box">
    <div
      class="item-input"
      :style="{color:disable?'#c6cad2':'#000'}"
      @click="showList"
    >{{searchStr ?searchStr:'请选择省市区'}}<i
        @click="clear"
        class="el-icon-circle-close"
      ></i></div>
    <div
      class="city-picker-area"
      v-if="done"
    >
      <div class="city-picker-inner">
        <div class="tabs">
          <ul class="tab-inner">
            <li
              :class="['tab-item', 0 == searchList.length ?'active':'']"
              @click.stop="clickSearch('100000',-1)"
            > 全国</li>
            <li
              :class="['tab-item', index == searchList.length -1?'active':'']"
              v-for="(item, index) in searchList"
              :key="item.adcode + index"
              @click.stop="clickSearch(item.adcode,index)"
            > {{ item.name }}</li>
          </ul>
        </div>
        <div class="cards">
          <ul class="card-inner">
            <li
              class="card-item"
              v-for="(item, index) in allCity"
              :key="item.adcode + index"
              @click.stop="clickCity(item)"
            >
              <span :class="['card-name', lastName == item.name?'active':'']">{{item.name}}</span>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>

CSS

.item-input {
  position: relative;
  width: 100%;
  background: #f4f5f7;
  border-radius: 4px;
  transition: all 0.1s linear;
  border: none;
  height: 36px;
  line-height: 36px;
  padding-left: 15px;
  color: var(--ft-black);
  font-size: 14px;
  .el-icon-circle-close {
    display: none;
    position: absolute;
    right: 10px;
    top: 10px;
    font-size: 16px;
  }
  &:hover {
    .el-icon-circle-close {
      display: inline-block;
    }
  }
}
ul,
li {
  list-style: none;
}

.box {
  position: relative;
}
.city-picker-area {
  position: absolute;
  width: 100%;
  padding: 0 12px 12px;
  background-color: #fff;
  z-index: 999;
  margin-top: -4px;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba($color: #000000, $alpha: 0.06);
}
.tab-inner {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  height: 36px;
  font-size: 12px;
  margin-bottom: 2px;
  margin-top: 16px;
  border-bottom: 1px solid #ebedee;
  padding-left: 0;
  .tab-item {
    flex: 0 0 20%;
    margin-right: 2px;
    height: 100%;
    text-align: center;
    line-height: 36px;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    margin-bottom: -3px;
    font-size: 14px;
    font-weight: 400;
    color: #8e8e8e;
    text-align: left;
    cursor: pointer;
    &:hover {
      color: #ff3a3a;
    }
  }
  .active {
    color: #ff3a3a;
  }
}
.cards {
  padding: 0 10px;
  max-height: 200px;
  overflow-y: auto;
  &::-webkit-scrollbar {
    width: 0;
  }
  .card-inner {
    display: flex;
    flex-wrap: wrap;
    padding-left: 0;
    .card-item {
      flex: 0 0 25%;
      height: 30px;
      line-height: 30px;
      margin-bottom: 10px;
      overflow: hidden;
      .card-name {
        display: inline-block;
        width: 100%;
        padding: 0 10px;
        text-align: center;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
        color: #333;
        cursor: pointer;
        &:hover {
          color: #ff3a3a;
        }
      }
      .active {
        color: #ff3a3a;
      }
    }
  }
}

JS(VUE)  -- 地区组件

props: {
    value: Array,
    //是否可选择任意节点
    checkStrictly: {
      type: Boolean,
      default: false
    },
    //最多查询层级 3可到街道
    levelLimit: {
      type: Number,
      default: 3
    },
    disable: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    searchStr () {
      let str = ""
      this.searchList.forEach((item, index) => {
        if (index != 0) {
          str = str + " / " + item.name
        } else {
          str += item.name
        }
      });
      return str
    },
    lastName () {
      if (this.searchList.length != 0) {
        return this.searchList[this.searchList.length - 1].name
      }
      return "全国"
    }
  },
  watch: {
    searchStr: {
      handler (val) {
        this.$emit("updateTextArea", this.searchStr);
      }
    },
  },
  mounted () {
    this.getAreaData("100000", false);
    document.addEventListener('click', this.hideMenu);
  },
  data () {
    return {
      allCity: [],
      searchList: [],
      done: false,
      currentAreaList: [],   // 当前查询到的省份编码
    }
  },
  beforeDestroy () {
    document.removeEventListener('click', this.hideMenu);
  },
  methods: {
    hideMenu (e) {
      e.stopPropagation();
      if (e.target.className == "item-input" || e.target.className == "card-name" || e.target.className == "tab-item") {
        return
      } else {
        this.done = false;
      }
    },
    showList () {
      if (!this.disable) {
        this.done = true;
      }
    },
    initValue (val) {
      this.searchList = [];
      this.allCity = [];
      if (this.value && this.value.length != 0) {
        if (!this.checkStrictly) {
          if (this.value.length == 4) {
            let index = this.value.length - 2;
            let name = this.value[index + 1];
            for (let i = 0; i <= index; i++) {
              let cityCode = this.value[i]
              this.getAreaDataByCode(cityCode).then(res => {
                this.$set(this.searchList, i, res.data.districts[0]);
                res.data.districts[0].districts.forEach((item) => {
                  if (item.name == name) {
                    this.$set(this.searchList, i + 1, item);
                    this.allCity = res.data.districts[0].districts;
                  }
                })
              })
            }
          } else {
            let index = this.value.length - 1;
            for (let i = 0; i <= index; i++) {
              let cityCode = this.value[i]
              if (cityCode) {
                this.getAreaDataByCode(cityCode).then(res => {
                  this.$set(this.searchList, i, res.data.districts[0]);
                  if (i == index) {
                    this.allCity = res.data.districts[0].districts;
                  }
                })
              }
            }
          }
        } else {
          if (this.value.length == 4) {
            let index = this.value.length - 2;
            let name = this.value[index + 1];
            for (let i = 0; i <= index; i++) {
              let cityCode = this.value[i]
              if (cityCode) {
                this.getAreaDataByCode(cityCode).then(res => {
                  this.$set(this.searchList, i, res.data.districts[0]);
                  res.data.districts[0].districts.forEach((item) => {
                    if (item.name == name) {
                      this.$set(this.searchList, i + 1, item);
                      this.allCity = res.data.districts[0].districts;
                    }
                  })
                })
              }
            }
          } else {
            let index = this.value.length - 1;
            for (let i = 0; i <= index; i++) {
              let cityCode = this.value[i]
              if (cityCode) {
                this.getAreaDataByCode(cityCode).then(res => {
                  this.$set(this.searchList, i, res.data.districts[0]);
                  if (i == index) {
                    this.allCity = res.data.districts[0].districts;
                  }
                })
              }
            }
          }
        }
      } else {
        this.getAreaData("100000", false);
      }
    },
    showSearch () {
      this.done = !this.done;
    },
    clear () {
      if (!this.disable) {
        this.currentAreaList = [];
        this.done = false;
        this.searchList = [];
        this.getAreaData("100000", false);
        this.$emit("updateCityList", this.currentAreaList);
        // 更新fulltext
        this.$emit("updateTextArea", this.searchStr);
        this.$emit("input", this.currentAreaList)
      }
    },
    clickCity (data) {
      if (data.level == "province") {
        this.$set(this.searchList, "0", data);
      } else if (data.level == "city") {
        this.$set(this.searchList, "1", data);
      } else if (data.level == "district") {
        this.$set(this.searchList, "2", data);
      } else {
        if (this.searchList.length == 2) {
          // 长度为2
          if (this.searchList[this.searchList.length - 1].level == "street") {
            this.$set(this.searchList, this.searchList.length - 1, data);
          } else {
            this.$set(this.searchList, "2", data);
          }
        } else {
          if (this.searchList[this.searchList.length - 1].level == "street") {
            this.$set(this.searchList, this.searchList.length - 1, data);
          } else {
            this.$set(this.searchList, "3", data);
          }
        }
        this.done = false;
        if (!this.checkStrictly) {
          this.currentAreaList = []
          this.searchList.forEach((item) => {
            if (item.level != "street") {
              this.currentAreaList.push(item.adcode)
            } else {
              this.currentAreaList.push(item.name)
            }
          })
          this.$emit("updateCityList", this.currentAreaList);
          this.$emit("input", this.currentAreaList)
        }
      }
      if (data.level != "street") {
        this.getAreaData(data.adcode, false);
      }
      if (this.checkStrictly) {
        this.currentAreaList = []
        this.searchList.forEach((item) => {
          if (item.level != "street") {
            this.currentAreaList.push(item.adcode)
          } else {
            this.currentAreaList.push(item.name)
          }
        })
        this.$emit("updateCityList", this.currentAreaList);
        this.$emit("input", this.currentAreaList)
      }
    },
    clickSearch (adcode, index) {
      this.getAreaData(adcode);
      if (index == -1) {
        this.searchList = [];
        this.currentAreaList = []
        this.$emit("updateCityList", this.currentAreaList);
        this.$emit("input", this.currentAreaList)
      } else {
        this.searchList = this.searchList.slice(0, index + 1);
        this.currentAreaList = []
        this.searchList.forEach((item) => {
          if (item.level != "street") {
            this.currentAreaList.push(item.adcode)
          } else {
            this.currentAreaList.push(item.name)
          }
        })
        this.$emit("updateCityList", this.currentAreaList);
        this.$emit("input", this.currentAreaList)
      }
    },
    getAreaDataByCode (code) {
      return axios
        // get地址替换为自己项目的高德地图 district地址
        .get("/amap/v3/config/district", {
          params: {
            keywords: code,
            subdistrict: 1,
            key: "高德地图key",
          },
        })
    },
    getAreaData (code, isLeaf) {
      this.getAreaDataByCode(code).then(res => {
        this.allCity = res.data.districts[0].districts;
      })
    },
  }

js--- 根据输入内容自动查找所在地区

search (location, data) {
     axios.get("/wsqq/ws/geocoder/v1/", { // 根据经纬度获取街道
        params: {
          key: "腾讯地图key",
          location: location
        }
      }).then((res) => {
        let street = res.data.result.address_reference.town.title;
        let areaCode = res.data.result.ad_info.adcode;
        let cityCode = res.data.result.ad_info.adcode.substr(0, 4) + "00";
        let provinceCode = res.data.result.ad_info.adcode.substr(0, 2) + "0000";
        this.$set(this.form, "areaCode", areaCode);
        this.$set(this.form, "cityCode", cityCode);
        this.$set(this.form, "provinceCode", provinceCode);
        this.$set(this.form, "streetCode", street);
        this.$set(this.form, "areaList", [provinceCode, cityCode, areaCode, street])
        this.$nextTick(() => {
            // 上部分介绍到的vue组件  调用器initValue方法进行查找
          this.$refs.areaTree.initValue();
          this.$refs.form.clearValidate("areaList")
        })
        this.isSearch = false;
      }).catch(err => {
        this.isSearch = false;
      })
    },
    // 根据监听输入地址的变化进行查询
    inputAddress () {
      if (this.searchTimer) {
        clearTimeout(this.searchTimer)
      }
      this.searchTimer = setTimeout(() => {
        if (this.form.detailedAddress != "") {
          this.isSearch = true;
          axios
             // 替换为自己项目的腾讯地图api
            .get("/wsqq/ws/geocoder/v1/", {
              params: {
                address: this.form.detailedAddress,
                key: "腾讯地址key",
                get_poi: 1
              },
            })
            .then((res) => {
              if (res.data.result) {
                let location = res.data.result.location;
                this.form.lon = location.lng + "";
                this.form.lat = location.lat + "";
                this.form.lonlat = location.lng + "," + location.lat;
                this.search(location.lat + "," + location.lng, res.data.result)
              } else {
                this.$message.error('请确认地址是否输入正确')
                this.isSearch = false;
              }
            });
        } else {
          this.form.lon = "";
          this.form.lat = "";
          this.form.lonlat = "";
        }
      }, 500);
    },

// 监听器部分
  watch: {
    "form.detailedAddress": {
      handler (val) {
        if (val) {
          this.inputAddress();
        }
      },
      immediate: true
    }
  },

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值