<!--
* @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;
}