|
|
<template>
|
|
|
<div class="address-select-component">
|
|
|
<div class="address-select-box">
|
|
|
<div class="component-title">
|
|
|
<span class="title">选择地区</span>
|
|
|
<span class="icon-close close" @click="closeAddBox"></span>
|
|
|
</div>
|
|
|
|
|
|
<ul class="head-address-ul">
|
|
|
<li
|
|
|
v-if="province.title"
|
|
|
:class="{ 'head-address-li': province.titleActive }"
|
|
|
>{{province.title}}</li>
|
|
|
<li
|
|
|
v-if="city.title"
|
|
|
:class="{ 'head-address-li': city.titleActive }"
|
|
|
@click="clickTitle('city')"
|
|
|
>{{city.title}}</li>
|
|
|
<li
|
|
|
v-if="area.title"
|
|
|
:class="{ 'head-address-li': area.titleActive }"
|
|
|
@click="clickTitle('area')"
|
|
|
>{{area.title}}</li>
|
|
|
<li
|
|
|
v-if="street.title"
|
|
|
:class="{ 'head-address-li': street.titleActive }"
|
|
|
@click="clickTitle('street')"
|
|
|
>{{street.title}}</li>
|
|
|
</ul>
|
|
|
|
|
|
<div class="address-container">
|
|
|
<div class="address-content">
|
|
|
<ul v-if="province.showList" class="address-ul">
|
|
|
<li
|
|
|
v-for="(pprovince, index) in provinces"
|
|
|
:key="index"
|
|
|
:class="{active: pprovince.id === province.id}"
|
|
|
>
|
|
|
{{pprovince.caption}}
|
|
|
<span v-if="pprovince.id === province.id" class="icon-check"></span>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<ul v-if="city.showList" class="address-ul">
|
|
|
<li
|
|
|
v-for="(pcity, index) in citys"
|
|
|
:key="index"
|
|
|
:class="{active: pcity.id === city.id}"
|
|
|
@click="switchAddress(pcity.id, pcity.caption)"
|
|
|
>
|
|
|
{{pcity.caption}}
|
|
|
<span v-if="pcity.id === city.id" class="icon-check"></span>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<ul v-if="area.showList" class="address-ul">
|
|
|
<li
|
|
|
v-for="(parea, index) in areas"
|
|
|
:key="index"
|
|
|
:class="{active: parea.id === area.id}"
|
|
|
@click="switchAddress(parea.id, parea.caption)"
|
|
|
>
|
|
|
{{parea.caption}}
|
|
|
<span v-if="parea.id === area.id" class="icon-check"></span>
|
|
|
</li>
|
|
|
</ul>
|
|
|
<ul v-if="street.showList" class="address-ul">
|
|
|
<li
|
|
|
v-for="(pstreet, index) in streets"
|
|
|
:key="index"
|
|
|
:class="{active: pstreet.id === street.id}"
|
|
|
@click="switchAddress(pstreet.id, pstreet.caption)"
|
|
|
>
|
|
|
{{pstreet.caption}}
|
|
|
<span v-if="pstreet.id === street.id" class="icon-check"></span>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { createNamespacedHelpers } from "vuex";
|
|
|
const { mapState, mapMutations, mapActions } = createNamespacedHelpers(
|
|
|
"address/address"
|
|
|
);
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
provinces: [],
|
|
|
citys: [],
|
|
|
areas: [],
|
|
|
streets: [],
|
|
|
province: {
|
|
|
id: "",
|
|
|
title: "",
|
|
|
allTitle: "",
|
|
|
showList: false,
|
|
|
titleActive: false
|
|
|
},
|
|
|
city: {
|
|
|
id: "",
|
|
|
title: "",
|
|
|
allTitle: "",
|
|
|
showList: false,
|
|
|
titleActive: false
|
|
|
},
|
|
|
area: {
|
|
|
id: "",
|
|
|
title: "",
|
|
|
allTitle: "",
|
|
|
showList: false,
|
|
|
titleActive: false
|
|
|
},
|
|
|
street: {
|
|
|
id: "",
|
|
|
title: "",
|
|
|
allTitle: "",
|
|
|
showList: false,
|
|
|
titleActive: false
|
|
|
}
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
|
...mapState(["provincesList"])
|
|
|
},
|
|
|
methods: {
|
|
|
...mapMutations({}),
|
|
|
...mapActions(["fetchAddressProvinces"]),
|
|
|
|
|
|
/* 处理编辑时父组件传递的省市区 */
|
|
|
async parentHandleclick({ areaCode, provinceTitle }) {
|
|
|
if (areaCode === "" || areaCode === undefined) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (areaCode.length < 2) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//省
|
|
|
this.province.allTitle = provinceTitle;
|
|
|
this.province.title = this.titleHandle(provinceTitle);
|
|
|
|
|
|
if (areaCode.length < 4) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//市
|
|
|
let citysCaption = "";
|
|
|
this.city.id = areaCode.substring(0, 4);
|
|
|
const cityResult = await this.fetchAddressProvinces(
|
|
|
areaCode.substring(0, 2)
|
|
|
);
|
|
|
this.citys = cityResult.data;
|
|
|
this.citys.map(info => {
|
|
|
if (info.id === this.city.id) {
|
|
|
citysCaption = info.caption;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
this.city.allTitle = citysCaption;
|
|
|
this.city.title = this.titleHandle(citysCaption);
|
|
|
|
|
|
if (areaCode.length < 6) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//县
|
|
|
let areasCaption = "";
|
|
|
this.area.id = areaCode.substring(0, 6);
|
|
|
const areaResult = await this.fetchAddressProvinces(
|
|
|
areaCode.substring(0, 4)
|
|
|
);
|
|
|
this.areas = areaResult.data;
|
|
|
|
|
|
this.areas.map(info => {
|
|
|
if (info.id === this.area.id) {
|
|
|
areasCaption = info.caption;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
this.area.allTitle = areasCaption;
|
|
|
this.area.title = this.titleHandle(areasCaption);
|
|
|
|
|
|
if (areaCode.length < 9) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
//街道
|
|
|
let streetsCaption = "";
|
|
|
this.street.id = areaCode.substring(0, 9);
|
|
|
const result = await this.fetchAddressProvinces(areaCode.substring(0, 6));
|
|
|
this.streets = result.data;
|
|
|
this.streets.map(info => {
|
|
|
if (info.id === this.street.id) {
|
|
|
streetsCaption = info.caption;
|
|
|
}
|
|
|
});
|
|
|
|
|
|
this.street.allTitle = streetsCaption;
|
|
|
this.street.title = this.titleHandle(streetsCaption);
|
|
|
|
|
|
this.street.showList = this.street.titleActive = true;
|
|
|
this.province.showList = this.city.showList = this.area.showList = false;
|
|
|
this.province.titleActive = this.city.titleActive = this.area.titleActive = false;
|
|
|
},
|
|
|
|
|
|
/* 获取地址数据绑定 */
|
|
|
async switchAddress(id, caption) {
|
|
|
if (!id) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this.changeShow(id, caption);
|
|
|
|
|
|
const result = await this.fetchAddressProvinces(id);
|
|
|
let resultData = result.data;
|
|
|
|
|
|
//length小于1时弹窗消失并传数据给上层
|
|
|
if (resultData && resultData.length < 1) {
|
|
|
let returnTitle = this.returnTitle();
|
|
|
|
|
|
this.$emit("popHidden");
|
|
|
this.$emit("modifyAreaInfo", {
|
|
|
code: id,
|
|
|
area: returnTitle
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/* 数据绑定 */
|
|
|
switch ((id + "").length) {
|
|
|
case 2:
|
|
|
this.citys = resultData;
|
|
|
break;
|
|
|
case 4:
|
|
|
this.areas = resultData;
|
|
|
break;
|
|
|
case 6:
|
|
|
this.streets = resultData;
|
|
|
break;
|
|
|
default:
|
|
|
this.provinces = resultData;
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
/* 选择地址后的显示控制 */
|
|
|
changeShow(id, caption) {
|
|
|
switch ((id + "").length) {
|
|
|
case 2:
|
|
|
if (this.province.id && this.province.id !== id) {
|
|
|
this.area.title = this.street.title = "";
|
|
|
}
|
|
|
|
|
|
this.city.title = "请选择";
|
|
|
|
|
|
this.province.id = id;
|
|
|
this.province.allTitle = caption;
|
|
|
this.province.title = this.titleHandle(caption);
|
|
|
|
|
|
this.city.showList = this.city.titleActive = true;
|
|
|
this.province.showList = this.area.showList = this.street.showList = false;
|
|
|
this.province.titleActive = this.area.titleActive = this.street.titleActive = false;
|
|
|
break;
|
|
|
case 4:
|
|
|
if (this.city.id && this.city.id !== id) {
|
|
|
this.street.title = "";
|
|
|
}
|
|
|
|
|
|
this.area.title = "请选择";
|
|
|
|
|
|
this.city.id = id;
|
|
|
this.city.allTitle = caption;
|
|
|
this.city.title = this.titleHandle(caption);
|
|
|
|
|
|
this.area.showList = this.area.titleActive = true;
|
|
|
this.province.showList = this.city.showList = this.street.showList = false;
|
|
|
this.province.titleActive = this.city.titleActive = this.street.titleActive = false;
|
|
|
break;
|
|
|
case 6:
|
|
|
this.street.title = "请选择";
|
|
|
|
|
|
this.area.id = id;
|
|
|
this.area.allTitle = caption;
|
|
|
this.area.title = this.titleHandle(caption);
|
|
|
|
|
|
this.street.showList = this.street.titleActive = true;
|
|
|
this.province.showList = this.city.showList = this.area.showList = false;
|
|
|
this.province.titleActive = this.city.titleActive = this.area.titleActive = false;
|
|
|
break;
|
|
|
case 9:
|
|
|
this.street.id = id;
|
|
|
this.street.allTitle = caption;
|
|
|
this.street.title = this.titleHandle(caption);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
if (this.province.id.length === 0) {
|
|
|
this.province.title = "请选择";
|
|
|
}
|
|
|
|
|
|
this.province.showList = this.province.titleActive = true;
|
|
|
this.city.showList = this.area.showList = this.street.showList = false;
|
|
|
this.city.titleActive = this.area.titleActive = this.street.titleActive = false;
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
/* 点击地址标题时的处理 */
|
|
|
clickTitle(type) {
|
|
|
switch (type) {
|
|
|
case "city":
|
|
|
this.city.titleActive = true;
|
|
|
this.city.showList = true;
|
|
|
|
|
|
this.province.titleActive = this.area.titleActive = this.street.titleActive = false;
|
|
|
this.province.showList = this.area.showList = this.street.showList = false;
|
|
|
break;
|
|
|
case "area":
|
|
|
this.area.titleActive = true;
|
|
|
this.area.showList = true;
|
|
|
|
|
|
this.province.titleActive = this.city.titleActive = this.street.titleActive = false;
|
|
|
this.province.showList = this.city.showList = this.street.showList = false;
|
|
|
break;
|
|
|
|
|
|
case "street":
|
|
|
this.street.titleActive = true;
|
|
|
this.street.showList = true;
|
|
|
|
|
|
this.province.titleActive = this.city.titleActive = this.area.titleActive = false;
|
|
|
this.province.showList = this.city.showList = this.area.showList = false;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
/* 关闭地址选择组件 */
|
|
|
closeAddBox() {
|
|
|
this.$emit("popHidden");
|
|
|
},
|
|
|
|
|
|
/* 返回标题处理 */
|
|
|
returnTitle() {
|
|
|
let getTitle = "";
|
|
|
let returnTitle = "";
|
|
|
|
|
|
getTitle =
|
|
|
this.province.allTitle +
|
|
|
this.city.allTitle +
|
|
|
this.area.allTitle +
|
|
|
this.street.allTitle;
|
|
|
|
|
|
if (getTitle.length > 18) {
|
|
|
returnTitle = getTitle.substr(0, 8) + "..." + getTitle.substr(-8);
|
|
|
} else {
|
|
|
returnTitle = getTitle;
|
|
|
}
|
|
|
|
|
|
return returnTitle;
|
|
|
},
|
|
|
|
|
|
/* 标题长度处理 */
|
|
|
titleHandle(caption) {
|
|
|
if (caption && caption.length > 3) {
|
|
|
return caption.substring(0, 3) + "...";
|
|
|
} else {
|
|
|
return caption;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
activated() {
|
|
|
// 重置data数据
|
|
|
Object.assign(this.$data, this.$options.data());
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
|
.disable {
|
|
|
color: #a6a6a6;
|
|
|
}
|
|
|
|
|
|
.address-select-component {
|
|
|
position: fixed;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
top: 0;
|
|
|
width: 100%;
|
|
|
background: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
.address-select-box {
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
background: #fff;
|
|
|
|
|
|
.component-title {
|
|
|
text-align: center;
|
|
|
line-height: 88px;
|
|
|
font-size: 34px;
|
|
|
font-weight: bold;
|
|
|
color: #000;
|
|
|
padding: 0 30px;
|
|
|
|
|
|
.close {
|
|
|
float: right;
|
|
|
}
|
|
|
|
|
|
.icon-close {
|
|
|
height: 40px;
|
|
|
width: 40px;
|
|
|
margin-top: 24px;
|
|
|
background: url("~statics/image/address/close.png");
|
|
|
background-size: cover;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.head-address-ul {
|
|
|
padding: 0;
|
|
|
margin: 0 0 0 30px;
|
|
|
list-style: none;
|
|
|
overflow: hidden;
|
|
|
font-size: 28px;
|
|
|
color: #999;
|
|
|
|
|
|
li {
|
|
|
display: block;
|
|
|
float: left;
|
|
|
height: 60px;
|
|
|
font-size: 28px;
|
|
|
line-height: 60px;
|
|
|
position: relative;
|
|
|
margin-right: 70px;
|
|
|
}
|
|
|
|
|
|
li:last-child {
|
|
|
margin-right: 30px;
|
|
|
}
|
|
|
|
|
|
.head-address-li {
|
|
|
color: #000;
|
|
|
}
|
|
|
|
|
|
.head-address-li:after {
|
|
|
width: 100%;
|
|
|
border-bottom: 4px solid #000;
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
left: 0;
|
|
|
content: "";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.address-container {
|
|
|
margin: 0;
|
|
|
overflow: hidden;
|
|
|
height: 100%;
|
|
|
width: 100%;
|
|
|
border-top: solid 1px #eee;
|
|
|
|
|
|
.address-content {
|
|
|
transform: translate(0, 0) translateZ(0);
|
|
|
height: 620px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.address-ul {
|
|
|
padding: 0;
|
|
|
margin: 0;
|
|
|
list-style: none;
|
|
|
height: 100%;
|
|
|
overflow: auto;
|
|
|
font-size: 28px;
|
|
|
color: #999;
|
|
|
justify-content: center;
|
|
|
|
|
|
li {
|
|
|
height: 80px;
|
|
|
line-height: 80px;
|
|
|
padding-left: 30px;
|
|
|
position: relative;
|
|
|
overflow: hidden;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
&.active {
|
|
|
font-size: 30px;
|
|
|
color: #000;
|
|
|
font-weight: bold;
|
|
|
}
|
|
|
|
|
|
.icon-check {
|
|
|
display: inline-block;
|
|
|
margin-left: 18px;
|
|
|
height: 30px;
|
|
|
width: 30px;
|
|
|
background-repeat: no-repeat;
|
|
|
background: url("~statics/image/address/check.png");
|
|
|
background-size: 100% 100%;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</style> |
...
|
...
|
|