省市区的联动

<!--
 * @Author: baike
 * @LastEditors: baike
-->
<template>
  <div class="city_info">
    <div class="lable_p">投放地域</div>
    <div>
      <el-radio-group size="small" v-model="radio1">
        <el-radio-button label="1">不限</el-radio-button>
        <el-radio-button label="2">省市</el-radio-button>
      </el-radio-group>
    </div>
    <template v-if="radio1 == 2">
      <el-input
        placeholder="请输入汉字省市名称进行搜索"
        v-model="val"
        class="_input"
        @input="hanldeSeach"
        prefix-icon="el-icon-search"
      >
      </el-input>
      <div class="city_box">
        <template v-if="!val">
          <div>
            <div class="li_head">
              <div>省份</div>
              <div class="check" @click="hanldeParentAll">全选</div>
            </div>
            <div class="_li">
              <div
                v-for="(item, index) in option"
                :id="item.isTrue ? 'li_ckeck' : ''"
                :key="item.label"
                class="li_ckeck"
                @click.stop="hanldeClick(item, index)"
              >
                <div class="_text">
                  <span
                    @click.stop="hanldeChildCheck(item, index)"
                    :class="item.check ? 'check_boxs' : 'check_box'"
                  ></span>
                  <span>{{ item.label }}</span>
                </div>
                <div class="text_r">
                  <i class="el-icon-arrow-right"></i>
                </div>
              </div>
            </div>
          </div>
          <div>
            <div class="li_head">
              <div>城市</div>
              <div class="check" @click="hanldeAll">全选</div>
            </div>
            <div class="_li">
              <div
                v-for="item in option[index].children"
                :id="item.isTrue ? 'li_ckeck' : ''"
                :key="item.label"
                class="li_ckeck"
                @click="hanldeChild(item, index)"
              >
                <div class="_text">
                  <span :class="item.isTrue ? 'check_boxs' : 'check_box'"></span
                  >{{ item.label }}
                </div>
                <div class="text_r"></div>
              </div>
            </div>
          </div>
        </template>
        <template v-if="val && copyArr.length">
          <div>
            <div class="li_head">
              <div>省份</div>
            </div>
            <div class="_li">
              <div
                v-for="(item, index) in copyArr"
                :id="item.isTrue ? 'li_ckeck' : ''"
                :key="item.label"
                class="li_ckeck"
                @click.stop="hanldeClick(item, index)"
              >
                <div class="_text">
                  <span
                    @click.stop="hanldeChildCheck(item, index)"
                    :class="item.check ? 'check_boxs' : 'check_box'"
                  ></span>

                  <span>{{ item.label }}</span>
                </div>
                <div class="text_r">
                  <i class="el-icon-arrow-right"></i>
                </div>
              </div>
            </div>
          </div>
          <div>
            <div class="li_head">
              <div>城市</div>
              <!-- <div class="check" @click="hanldeAll">全选</div> -->
            </div>
            <div class="_li">
              <div
                v-for="item in copyArr[0].children"
                :id="item.isTrue ? 'li_ckeck' : ''"
                :key="item.label"
                class="li_ckeck"
                @click="hanldeChildSearch(item)"
              >
                <div class="_text">
                  <span
                    :class="item.isTrue ? 'check_boxs' : 'check_box'"
                  ></span>
                  {{ item.label }}
                </div>
                <div class="text_r"></div>
              </div>
            </div>
          </div>
        </template>
        <div>
          <div class="li_head">
            <div>已选</div>
            <div @click="onClear" class="check">清空</div>
          </div>
          <div class="_li li_c">
            <el-alert
              v-for="(item, i) in checkArr"
              :key="item.label"
              class="alert"
              :title="item.label"
              @close="hanldeClose(item, i)"
              type="info"
            >
            </el-alert>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>
<script>
import { transformData } from "./city.js";

export default {
  props: {
    value: {
      type: Object,
      default: () => {},
    },
  },
  components: {},
  computed: {
    from: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit("input", val);
      },
    },
  },
  data() {
    return {
      option: [],
      val: "",
      radio1: 2,
      childArr: [],
      index: 0,

      checkArr: [],
      copyArr: [],
      cityArr: ["北京市", "天津市", "上海市", "重庆市"],
    };
  },
  mounted() {
    this.option = transformData();
  },
  methods: {
    // 省 全选
    hanldeParentAll() {
      this.checkArr = [];
      this.option.forEach((item) => {
        this.$set(item, "isTrue", true);
        this.$set(item, "check", true);
        item.children.forEach((ite) => {
          this.$set(ite, "isTrue", true);
        });
      });
      this.checkArr = this.option.map((item) => {
        return { label: item.label, children: item.children };
      });
      this.$forceUpdate();
    },
    // 省 单选
    hanldeClick(item, index) {
      this.index = index;
      this.checkParent();
      this.$set(item, "isTrue", true);
      this.$forceUpdate();
    },
    // check 省 选中
    hanldeChildCheck(item, index) {
      this.index = index;
      // 勾选
      if (!item.check) {
        //
        if (this.cityArr.includes(item.label)) {
          this.checkArr.push({
            label: item.label,
            children: [],
          });
        } else {
          this.checkArr.push({
            label: item.label,
            children: item.children,
          });
          this.checkArr = this.checkArr.filter((ite) => {
            return !item.children.find((i) => {
              return ite.label == i.label;
            });
          });
        }
      } else {
        // 反选
        let Id = this.checkArr.findIndex((v) => v.label == item.label);
        if (Id != "-1") {
          this.checkArr.splice(Id, 1);
        } else {
          this.checkArr = this.checkArr.filter((ite, index) => {
            return !item.children.find((i) => {
              return ite.label == i.label;
            });
          });
        }
      }
      this.$set(item, "check", !item.check);
      this.$set(item, "isTrue", !item.isTrue);
      // 市级 选中
      item.children.forEach((i) => {
        this.$set(i, "isTrue", item.check);
      });
      this.$forceUpdate();
    },
    // 省选中
    checkParent() {
      this.option.forEach((item) => {
        item.isTrue = false;
        item.check = false;
      });
      this.option.forEach((item) => {
        item.children.forEach((ite) => {
          if (ite.isTrue) {
            this.$set(item, "isTrue", true);
            this.$set(item, "check", true);
          }
        });
      });
    },
    // 市单选后如果全部选择后 =>锁定省
    getParentCheck(v, index) {
      if (this.cityArr.includes(this.option[index].label)) return;
      let flag = this.option[index].children.some((item) => !item.isTrue);
      if (!flag) {
        this.checkArr.push({
          label: this.option[index].label,
          children: this.option[index].children,
        });
        this.checkArr = this.checkArr.filter((ite) => {
          return !this.option[index].children.find((item) => {
            return ite.label == item.label;
          });
        });
      }
    },
    // 市
    hanldeChild(item, index) {
      this.hanldeTwoCheck(item, index);
      // 刷新省
      this.checkParent();
      // 通过单选 选择全部
      this.getParentCheck(item, index);
    },

    hanldeChildSearch(item) {
      var index;
      this.option.forEach((v, i) => {
        if (v.label == this.copyArr[0].label) {
          index = i;
        }
      });
      this.hanldeChild(item, index);
    },
    // 单选 =>反选计算
    hanldeTwoCheck(item, index) {
      this.$set(item, "isTrue", !item.isTrue);
      // 反选
      if (!item.isTrue) {
        let Id = this.checkArr.findIndex((v) => v.label == item.label);
        // 市级 未全部勾选
        if (Id != "-1") {
          this.checkArr.splice(Id, 1);
        } else {
          // 市级全部勾选
          let ids = this.checkArr.findIndex(
            (v) => v.label == this.option[index].label
          );
          this.checkArr.splice(ids, 1);
          // 当前市 选中的
          let checks = this.option[index].children.map((child) => {
            return {
              label: child.label,
              children: [],
            };
          });
          this.checkArr = this.checkArr.concat(checks);
        }
      } else {
        this.checkArr.push({
          label: item.label,
          children: [],
        });
      }
      this.$forceUpdate();
    },
    // 全选-市级
    hanldeAll() {
      this.option[this.index].children.forEach((item) => {
        this.$set(item, "isTrue", true);
      });
      let flag = this.checkArr.some(
        (item) => item.label == this.option[this.index].label
      );
      // 去重
      if (flag) return;
      if (this.cityArr.includes(this.option[this.index].label)) {
        this.checkArr.push({
          label: this.option[this.index].label,
          children: [],
        });
      } else {
        this.checkArr.push({
          label: this.option[this.index].label,
          children: this.option[this.index].children,
        });

        // 去重
        this.checkArr = this.checkArr.filter((ite) => {
          return !this.option[this.index].children.find((item) => {
            return ite.label == item.label;
          });
        });
      }
      this.checkParent();
      this.$forceUpdate();
    },
    // 删除单个
    hanldeClose(ite, index) {
      this.checkArr.splice(index, 1);
      this.option.forEach((item) => {
        // 省
        if (item.label == ite.label) {
          item.children.forEach((i) => {
            this.$set(i, "isTrue", false);
          });
        } else {
          item.children.forEach((i) => {
            // 市
            if (i.label == ite.label) {
              this.$set(i, "isTrue", false);
            }
          });
        }
      });

      // 刷新省
      this.checkParent();
      this.$forceUpdate();
    },
    // 清空
    onClear() {
      this.index = 0;
      this.checkArr = [];
      this.option.forEach((item) => {
        this.$set(item, "check", false);
        item.children.forEach((i) => {
          this.$set(i, "isTrue", false);
        });
      });
      // 刷新省
      this.checkParent();
      this.$forceUpdate();
    },
    // 搜索
    hanldeSeach() {
      if (this.val) {
        this.index = 0;
        this.copyArr = [];
        this.option.map((i, index) => {
          i.children.filter((ite) => {
            if (
              ite.label.indexOf(this.val) != "-1" ||
              i.label.indexOf(this.val) != "-1"
            ) {
              this.copyArr = [i];
            }
          });
        });
        this.checkParent();
      }
    },
  },
};
</script>

<style lang='scss' scoped>
.city_info {
  ._input {
    width: 500px;
    margin: 20px 0;
  }
  .check_box {
    width: 15px;
    height: 15px;
    border: 1px solid #797979;
    margin-right: 6px;
    display: inline-block;
    margin-top: 1px;
    position: relative;
  }
  .check_boxs {
    width: 15px;
    height: 15px;
    margin-right: 6px;
    display: inline-block;
    margin-top: 1px;
    position: relative;
    border: 1px solid #2f6eff;
    background: #2f6eff;
  }
  .check_boxs::before {
    content: "";
    position: absolute;
    left: 0px;
    top: 2px;
    width: 13px;
    height: 6px;
    border: solid white;
    border-width: 2px 2px 0 0;
    -webkit-transform: rotate(-237deg);
    transform: rotate(-237deg);
  }
  .city_box {
    display: flex;
    ._li {
      width: 300px;
      height: 400px;
      overflow-y: scroll;
      border: 1px solid #efefef;
    }
    .li_head {
      display: flex;
      justify-content: space-between;
      padding: 10px;
      border: 1px solid #efefef;

      .check {
        color: #0067c3;
        cursor: prgb(25, 32, 37);
        cursor: pointer;
      }
    }
    .li_ckeck {
      display: flex;
      justify-content: space-between;
      padding: 10px;
      cursor: pointer;
      font-size: 14px;
    }
    ._text {
      display: flex;
    }
    .li_ckeck:hover {
      color: #0067c3;
      font-weight: 700;
    }
    #li_ckeck {
      color: #0067c3;
      font-weight: 700;
    }
  }
  ._li::-webkit-scrollbar {
    display: none;
  }
  .lable_p {
    font-size: 14px;
    color: #606266;
    line-height: 40px;
    font-weight: 700;
  }
}
.li_c {
  padding: 5px;
}
.alert {
  margin-bottom: 5px;
}
</style>

city 

var srt = {
  北京市: ["北京市"],
  天津市: ["天津市"],
  河北省: [
    "石家庄市",
    "唐山市",
    "秦皇岛市",
    "邯郸市",
    "邢台市",
    "保定市",
    "张家口市",
    "承德市",
    "沧州市",
    "廊坊市",
    "衡水市"
  ],
  山西省: [
    "太原市",
    "大同市",
    "阳泉市",
    "长治市",
    "晋城市",
    "朔州市",
    "晋中市",
    "运城市",
    "忻州市",
    "临汾市",
    "吕梁市"
  ],
  内蒙古自治区: [
    "呼和浩特市",
    "包头市",
    "乌海市",
    "赤峰市",
    "通辽市",
    "鄂尔多斯市",
    "呼伦贝尔市",
    "巴彦淖尔市",
    "乌兰察布市",
    "兴安盟",
    "锡林郭勒盟",
    "阿拉善盟"
  ],
  辽宁省: [
    "沈阳市",
    "大连市",
    "鞍山市",
    "抚顺市",
    "本溪市",
    "丹东市",
    "锦州市",
    "营口市",
    "阜新市",
    "辽阳市",
    "盘锦市",
    "铁岭市",
    "朝阳市",
    "葫芦岛市"
  ],
  吉林省: [
    "长春市",
    "吉林市",
    "四平市",
    "辽源市",
    "通化市",
    "白山市",
    "松原市",
    "白城市",
    "延边朝鲜族自治州"
  ],
  黑龙江省: [
    "哈尔滨市",
    "齐齐哈尔市",
    "鸡西市",
    "鹤岗市",
    "双鸭山市",
    "大庆市",
    "伊春市",
    "佳木斯市",
    "七台河市",
    "牡丹江市",
    "黑河市",
    "绥化市",
    "大兴安岭地区"
  ],
  上海市: [
   '上海市'
  ],
  江苏省: [
    "南京市",
    "无锡市",
    "徐州市",
    "常州市",
    "苏州市",
    "南通市",
    "连云港市",
    "淮安市",
    "盐城市",
    "扬州市",
    "镇江市",
    "泰州市",
    "宿迁市"
  ],
  浙江省: [
    "杭州市",
    "宁波市",
    "温州市",
    "嘉兴市",
    "湖州市",
    "绍兴市",
    "金华市",
    "衢州市",
    "舟山市",
    "台州市",
    "丽水市"
  ],
  安徽省: [
    "合肥市",
    "芜湖市",
    "蚌埠市",
    "淮南市",
    "马鞍山市",
    "淮北市",
    "铜陵市",
    "安庆市",
    "黄山市",
    "滁州市",
    "阜阳市",
    "宿州市",
    "六安市",
    "亳州市",
    "池州市",
    "宣城市"
  ],
  福建省: [
    "福州市",
    "厦门市",
    "莆田市",
    "三明市",
    "泉州市",
    "漳州市",
    "南平市",
    "龙岩市",
    "宁德市"
  ],
  江西省: [
    "南昌市",
    "景德镇市",
    "萍乡市",
    "九江市",
    "新余市",
    "鹰潭市",
    "赣州市",
    "吉安市",
    "宜春市",
    "抚州市",
    "上饶市"
  ],
  山东省: [
    "济南市",
    "青岛市",
    "淄博市",
    "枣庄市",
    "东营市",
    "烟台市",
    "潍坊市",
    "济宁市",
    "泰安市",
    "威海市",
    "日照市",
    "临沂市",
    "德州市",
    "聊城市",
    "滨州市",
    "菏泽市"
  ],
  河南省: [
    "郑州市",
    "开封市",
    "洛阳市",
    "平顶山市",
    "安阳市",
    "鹤壁市",
    "新乡市",
    "焦作市",
    "濮阳市",
    "许昌市",
    "漯河市",
    "三门峡市",
    "南阳市",
    "商丘市",
    "信阳市",
    "周口市",
    "驻马店市",
    "济源市"
  ],
  湖北省: [
    "武汉市",
    "黄石市",
    "十堰市",
    "宜昌市",
    "襄阳市",
    "鄂州市",
    "荆门市",
    "孝感市",
    "荆州市",
    "黄冈市",
    "咸宁市",
    "随州市",
    "恩施土家族苗族自治州",
    "仙桃市",
    "潜江市",
    "天门市",
    "神农架林区"
  ],
  湖南省: [
    "长沙市",
    "株洲市",
    "湘潭市",
    "衡阳市",
    "邵阳市",
    "岳阳市",
    "常德市",
    "张家界市",
    "益阳市",
    "郴州市",
    "永州市",
    "怀化市",
    "娄底市",
    "湘西土家族苗族自治州"
  ],
  广东省: [
    "广州市",
    "韶关市",
    "深圳市",
    "珠海市",
    "汕头市",
    "佛山市",
    "江门市",
    "湛江市",
    "茂名市",
    "肇庆市",
    "惠州市",
    "梅州市",
    "汕尾市",
    "河源市",
    "阳江市",
    "清远市",
    "东莞市",
    "中山市",
    "潮州市",
    "揭阳市",
    "云浮市"
  ],
  广西壮族自治区: [
    "南宁市",
    "柳州市",
    "桂林市",
    "梧州市",
    "北海市",
    "防城港市",
    "钦州市",
    "贵港市",
    "玉林市",
    "百色市",
    "贺州市",
    "河池市",
    "来宾市",
    "崇左市"
  ],
  海南省: [
    "海口市",
    "三亚市",
    "三沙市",
    "儋州市",
    "五指山市",
    "琼海市",
    "文昌市",
    "万宁市",
    "东方市",
    "定安县",
    "屯昌县",
    "澄迈县",
    "临高县",
    "白沙黎族自治县",
    "昌江黎族自治县",
    "乐东黎族自治县",
    "陵水黎族自治县",
    "保亭黎族苗族自治县",
    "琼中黎族苗族自治县"
  ],
  重庆市: [
   '重庆市'
  ],
  四川省: [
    "成都市",
    "自贡市",
    "攀枝花市",
    "泸州市",
    "德阳市",
    "绵阳市",
    "广元市",
    "遂宁市",
    "内江市",
    "乐山市",
    "南充市",
    "眉山市",
    "宜宾市",
    "广安市",
    "达州市",
    "雅安市",
    "巴中市",
    "资阳市",
    "阿坝藏族羌族自治州",
    "甘孜藏族自治州",
    "凉山彝族自治州"
  ],
  贵州省: [
    "贵阳市",
    "六盘水市",
    "遵义市",
    "安顺市",
    "毕节市",
    "铜仁市",
    "黔西南布依族苗族自治州",
    "黔东南苗族侗族自治州",
    "黔南布依族苗族自治州"
  ],
  云南省: [
    "昆明市",
    "曲靖市",
    "玉溪市",
    "保山市",
    "昭通市",
    "丽江市",
    "普洱市",
    "临沧市",
    "楚雄彝族自治州",
    "红河哈尼族彝族自治州",
    "文山壮族苗族自治州",
    "西双版纳傣族自治州",
    "大理白族自治州",
    "德宏傣族景颇族自治州",
    "怒江傈僳族自治州",
    "迪庆藏族自治州"
  ],
  西藏自治区: [
    "拉萨市",
    "日喀则市",
    "昌都市",
    "林芝市",
    "山南市",
    "那曲市",
    "阿里地区"
  ],
  陕西省: [
    "西安市",
    "铜川市",
    "宝鸡市",
    "咸阳市",
    "渭南市",
    "延安市",
    "汉中市",
    "榆林市",
    "安康市",
    "商洛市"
  ],
  甘肃省: [
    "兰州市",
    "嘉峪关市",
    "金昌市",
    "白银市",
    "天水市",
    "武威市",
    "张掖市",
    "平凉市",
    "酒泉市",
    "庆阳市",
    "定西市",
    "陇南市",
    "临夏回族自治州",
    "甘南藏族自治州"
  ],
  青海省: [
    "西宁市",
    "海东市",
    "海北藏族自治州",
    "黄南藏族自治州",
    "海南藏族自治州",
    "果洛藏族自治州",
    "玉树藏族自治州",
    "海西蒙古族藏族自治州"
  ],
  宁夏回族自治区: ["银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"],
  新疆维吾尔自治区: [
    "乌鲁木齐市",
    "克拉玛依市",
    "吐鲁番市",
    "哈密市",
    "昌吉回族自治州",
    "博尔塔拉蒙古自治州",
    "巴音郭楞蒙古自治州",
    "阿克苏地区",
    "克孜勒苏柯尔克孜自治州",
    "喀什地区",
    "和田地区",
    "伊犁哈萨克自治州",
    "塔城地区",
    "阿勒泰地区",
    "石河子市",
    "阿拉尔市",
    "图木舒克市",
    "五家渠市",
    "北屯市",
    "铁门关市",
    "双河市",
    "可克达拉市",
    "昆玉市",
    "胡杨河市",
    "新星市",
    "白杨市"
  ]
};

export function transformData() {
  const result = [];

  // 遍历对象中的每一个省份
  for (const province in srt) {
    const cities = srt[province];
    const provinceObj = {
      label: province,
      children: []
    };

    // 遍历城市列表
    cities.forEach(city => {
      provinceObj.children.push({
        label: city
      });
    });

    // 将省份对象添加到结果数组中
    result.push(provinceObj);
  }

  return result;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值