uniapp 选择 省市区 省市 以及 回显



从gitee仓库可以拿到demo 以及 json省市区 文件

// 这是组件部分

html 复制代码
<template>
  <uni-popup ref="popup" type="bottom">
    <view class="popup">
      <view class="picker-btn">
        <view class="left" @click="cancel">取消</view>
        <view class="right" @click="confirm">确定</view>
      </view>
      <picker-view
        :indicator-style="indicatorStyle"
        :value="valueArr"
        @change="bindChange"
      >
        <picker-view-column>
          <view
            class="item"
            v-for="(item, index) in province[0]"
            :key="index"
            >{{ item.name }}</view
          >
        </picker-view-column>
        <picker-view-column v-if="province[1]">
          <view
            class="item"
            v-for="(item, index) in province[1]"
            :key="index"
            >{{ item.name }}</view
          >
        </picker-view-column>
        <picker-view-column v-if="province[2]">
          <view
            class="item"
            v-for="(item, index) in province[2]"
            :key="index"
            >{{ item.name }}</view
          >
        </picker-view-column>
      </picker-view>
    </view>
  </uni-popup>
</template>
<script>
import provinces from "./provinces.json";
import cities from "./cities.json";
import areas from "./areas.json";
export default {
  props: {
    value: {
      type: String,
      default: "",
    },

    twoStage: {
      type: Boolean,
      default: false,
    },
  },
  name: "ZlAddress",
  data() {
    return {
      indicatorStyle: `height: ${Math.round(
        uni.getSystemInfoSync().screenWidth / (750 / 100)
      )}px;`,
      valueArr: [0, 0, 0], // 用于判断当前滑动的是哪一列
      province: [provinces], // 数据列表
    };
  },

  methods: {
    setIndex(i, value) {
      this.$set(this.valueArr, i, value);
    },
    initLoadArea() {
      this.loadCity(provinces[0].code);
    },
    loadCity(code) {
      let children = cities.filter((v) => v.provinceCode == code);
      this.$set(this.province, 1, children);

      if (!this.twoStage) {
        this.loadArea(children[this.valueArr[1]]?.code || children[0].code);
      }
    },
    loadArea(code) {
      this.$set(
        this.province,
        2,
        areas.filter((v) => v.cityCode == code)
      );
    },

    bindChange(e) {
      const val = e.detail.value;
      if (this.valueArr[0] !== val[0]) {
        let code = provinces[val[0]].code;
        this.loadCity(code);
      } else if (this.valueArr[1] !== val[1]) {
        if (!this.twoStage) {
          let code = this.province[1][val[1]].code;
          this.loadArea(code);
        }
      }
      this.valueArr = val;
    },

    confirm() {
      let addressDetail = "";

      if (!this.twoStage) {
        addressDetail = `${this.province[0][this.valueArr[0]].name}-${
          this.province[1][this.valueArr[1]].name
        }-${this.province[2][this.valueArr[2]]?.name}`;
      } else {
        addressDetail = `${this.province[0][this.valueArr[0]].name}-${
          this.province[1][this.valueArr[1]].name
        }`;
      }

      this.$emit("confirm", addressDetail);
    },

    open() {
      this.$refs.popup.open();
      if (!this.value) {
        this.initLoadArea();
      } else {
        this.$nextTick(() => {
          this.echoLoad();
        });
      }
    },

    echoLoad() {
      let val = this.value.split("-");

      let sheng = provinces.findIndex((v) => v.name == val[0]);
      let shengcode = provinces.find((v) => v.name == val[0])?.code;
      this.setIndex(0, sheng);

      let children = cities.filter((v) => v.provinceCode == shengcode);
      this.$set(this.province, 1, children);
      let shi = this.province[1].findIndex((v) => v.name == val[1]);
      let shicode = this.province[1].find((v) => v.name == val[1])?.code;
      this.setIndex(1, shi);

      if (!this.twoStage) {
        let children2 = areas.filter((v) => v.cityCode == shicode);
        this.$set(this.province, 2, children2);
        let qu = this.province[2].findIndex((v) => v.name == val[2]);

        this.setIndex(2, qu);
      }
    },
    cancel() {
      this.$refs.popup.close();
    },
  },
};
</script>

<style lang="scss" scoped>
.popup {
  height: fit-content;
  width: 100%;
  background: #fff;
}

.picker-btn {
  display: flex;
  height: 100rpx;
  width: 100%;
  line-height: 100rpx;
  background: #fff;
  font-size: 34rpx;
  z-index: 1;
  border-bottom: 1rpx solid #f8f8f8;

  .left {
    flex: 1;
    color: #0076ff;
    padding-left: 40rpx;
    box-sizing: border-box;
  }

  .right {
    flex: 1;
    text-align: right;
    padding-right: 40rpx;
    color: #fe4533;
    box-sizing: border-box;
  }
}

picker-view {
  width: 100%;
  height: 500rpx;
  display: relative;
}
.item {
  line-height: 100rpx;
  text-align: center;
}
</style>

// 这是 使用部分

html 复制代码
<template>
  <view class="content">
    <div @click="changeAddress">
      {{ address ? address : "请选择省市区" }}
    </div>
    <Address :value="address" @confirm="confirmAddress" ref="address"></Address>

    <div @click="changeAddress2">
      {{ address2 ? address2 : "请选择省市" }}
    </div>
    <Address
      :value="address2"
      @confirm="confirmAddress2"
      ref="address2"
      two-stage
    ></Address>
  </view>
</template>

<script>
import Address from "@/components/address.vue";
export default {
  data() {
    return {
      address: "",
      address2: "",
    };
  },
  components: {
    Address,
  },
  onLoad() {},
  methods: {
    changeAddress() {
      this.$refs.address.open();
    },
    changeAddress2() {
      this.$refs.address2.open();
    },
    confirmAddress(val) {
      console.log(val, "eee");
      this.address = val;
      this.$refs.address.cancel();
    },
    confirmAddress2(val) {
      console.log(val, "eee");
      this.address2 = val;
      this.$refs.address2.cancel();
    },
  },
};
</script>

<style>
.content {
  display: flex;
  flex-direction: column;
  gap: 40rpx;
  padding: 40rpx;
}
</style>
相关推荐
晚风醉蝶13 小时前
DeepSeek 大模型落地应用与场景实践指南
大数据·人工智能
厦门德仔14 小时前
【YiFeiWebApi】易飞ERP与WMS系统接口对接实战:从0到1全流程指南
大数据·数据库
Neighbor_OldY14 小时前
线上服务CPU飙高接口超时应急处置实战:从load爆表到快速定位根因,一次线上救火全记录
大数据·运维
大大大大晴天️14 小时前
大数据上 K8s 的三种运行范式:离线计算、实时流处理与分析服务
大数据·kubernetes
2601_9620725014 小时前
大数据-234 离线数仓 - 异构数据源 DataX 将数据 从 HDFS 到 MySQL
大数据·mysql·hdfs
Elasticsearch15 小时前
从 22.61GB 到 15.63GB:Elasticsearch 9.5 如何用「混合存储」重新定义日志数据库
elasticsearch
Elasticsearch15 小时前
用于自托管 LLM 调优的 vLLM Prometheus 指标:TTFT、KV Cache 和 GPU 利用率
elasticsearch
一只专注api接口开发的技术猿15 小时前
Open Claw 实战|快速搭建电商商品监控与数据分析能力
大数据·数据库·数据挖掘·数据分析
Fxkj88815 小时前
企业新媒体IP陪跑真实价值解析:合作体验与效果评判标准
大数据·人工智能·tcp/ip·媒体
大金SEO16 小时前
注册商标企业,在做GEO优化时应选用哪类媒体,才更易被AI采纳?
大数据·人工智能