
vue 类似淘宝组件
1.组件
<template>
<div v-show="addressSelectShow" :style="{'left': leftValue + 'px', 'top': topValue + 'px' }" class="content">
<ul class="area-select">
<li v-for="(item, index) in areaMain" :key="index" :class="{'hasSelect':index === hasSelectIndex}" @click="changeArea(index)"> {{ item }} </li>
</ul>
<ul class="address-select">
<div v-show="hasSelectIndex === 0">
<li v-for="(item, index) in province" :key="index" :class="{'select-li-provice': index === pSelectLiIndex}" @click="selectProvince(index)"> {{ item.area_name }}</li>
</div>
<div v-show="hasSelectIndex === 1">
<li v-for="(item, index) in city" :key="index" :class="{'select-li-provice': index === cSelectLiIndex}" @click="selectCity(index)"> {{ item.area_name }}</li>
</div>
<div v-show="hasSelectIndex === 2">
<li v-for="(item, index) in area" :key="index" :class="{'select-li-provice': index === aSelectLiIndex}" @click="selectArea(index)"> {{ item.area_name }}</li>
</div>
<div v-show="hasSelectIndex === 3">
<li v-for="(item, index) in street" :key="index" :class="{'select-li-provice': index === sSelectLiIndex}" @click="selectStreet(index)"> {{ item.area_name }}</li>
</div>
</ul>
</div>
</template>
<script>
import { getProvince, getCity } from '@/api/address_select'
export default {
name: 'AddressSelect',
props: {
addressSelectShow: { // 控制是否显示地址选择
type: Boolean,
default: true
},
leftValue: { // 定位的离左边的距离
type: Number,
default: 600
},
topValue: { // 定位的离上边的距离
type: Number,
default: 100
}
},
data() {
return {
areaMain: ['省', '市', '区', '街道'],
hasSelectIndex: 0, // 控制显示第几个
province: [], // 循环的省份的值
city: [], // 循环的城市的值
area: [], // 循环的地区的值
street: [], // 循环的街道的值
pid: '', // 省份id
cid: '', // 城市id
aid: '', // 地区id
sid: '', // 街道id
pSelectLiIndex: '', // 选中的省的下标
cSelectLiIndex: '', // 选中的城市的下标
aSelectLiIndex: '', // 选中的地区的下标
sSelectLiIndex: '', // 选中的街道的下标
addressDetail: [], // 传给父组件的地址名称
addressId: [] // 传给父组件的地址id
}
},
mounted() {
this.getAllProvince()
},
methods: {
changeArea(index) { // 切换模块
switch (index) { // 判断是否上级有值,如果上级没值则不能切换
case 1:
if (!this.pid) {
return
}
break
case 2:
if (!this.pid || !this.cid) {
return
}
break
case 3:
if (!this.pid || !this.cid || !this.aid) {
return
}
break
default:
break
}
this.hasSelectIndex = index
},
getAllProvince() { // 获取省份列表
getProvince().then((res) => {
this.province = res.data
}).catch(() => {})
},
// 选择省份执行的事件
selectProvince(index) {
this.addressDetail = []
this.addressId = []
this.pid = this.province[index].id
this.pSelectLiIndex = index
this.cSelectLiIndex = ''
this.aSelectLiIndex = ''
this.sSelectLiIndex = ''
this.addressId[0] = this.province[index].id
this.addressDetail[0] = this.province[index].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
this.pSearchC()
},
// 省份查找城市
pSearchC() {
getCity(this.pid).then((res) => { // 获取省份下城市的列表
this.city = res.data
this.hasSelectIndex = 1
if (this.city.length === 1) { // 如果只有一条数据,则默认选中并执行下一次查找,其他位置同理
this.hasSelectIndex = 2
this.cSelectLiIndex = 0
this.cid = this.city[0].id
this.addressId.splice(1, this.addressId.length - 1)
this.addressDetail.splice(1, this.addressId.length - 1)
this.addressId[1] = this.city[0].id
this.addressDetail[1] = this.city[0].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
this.cSearchA()
}
}).catch(() => {})
},
// 选择市执行的事件
selectCity(index) {
this.cid = this.city[index].id
this.cSelectLiIndex = index
this.aSelectLiIndex = ''
this.sSelectLiIndex = ''
this.addressId.splice(index, this.addressId.length - 1)
this.addressId[1] = this.city[index].id
this.addressDetail.splice(1, this.addressDetail.length - 1)
this.addressDetail[1] = this.city[index].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
this.cSearchA()
},
// 市查找区
cSearchA() {
getCity(this.cid).then((res) => { // 获取城市下地区的列表
this.area = res.data
this.hasSelectIndex = 2
if (this.area.length === 1) {
this.hasSelectIndex = 3
this.aSelectLiIndex = 0
this.aid = this.area[0].id
this.addressId.splice(2, this.addressId.length - 1)
this.addressDetail.splice(2, this.addressId.length - 1)
this.addressId[2] = this.area[0].id
this.addressDetail[2] = this.area[0].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
this.aSearchS()
}
}).catch(() => {})
},
// 选择区执行的事件
selectArea(index) {
this.aid = this.area[index].id
this.aSelectLiIndex = index
this.sSelectLiIndex = ''
this.addressId.splice(2, this.addressId.length - 1)
this.addressId[2] = this.area[index].id
this.addressDetail.splice(2, this.addressId.length - 1)
this.addressDetail[2] = this.area[index].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
this.aSearchS()
},
// 区查找街道
aSearchS() {
getCity(this.aid).then((res) => { // 获取地区下街道的列表
this.street = res.data
const obj = {
id: '123456',
area_name: '暂不选择'
}
this.street.unshift(obj)
this.hasSelectIndex = 3
if (this.street.length === 1) {
this.sSelectLiIndex = 0
this.sid = this.street[0].id
this.addressId.splice(3, this.addressId.length - 1)
this.addressDetail.splice(3, this.addressId.length - 1)
this.addressId[3] = this.street[0].id
this.addressDetail[3] = this.street[0].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
}
}).catch(() => {})
},
// 选择区执行的事件
selectStreet(index) {
this.sid = this.street[index].id
this.sSelectLiIndex = index
this.addressId[3] = this.street[index].id
this.addressDetail[3] = this.street[index].area_name
this.$emit('getAddressDetail', this.addressDetail, this.addressId)
}
}
}
</script>
<style scoped rel="stylesheet/scss" lang="scss">
.content{
position: absolute;
z-index: 10;
background: white;
.area-select{
425px;
height: 30px;
margin: 0;
padding: 0;
border: 1px solid #CCCCCC;
li{
list-style: none;
float: left;
height: 28px;
line-height: 28px;
text-align: center;
background: #f0f0f0;
25%;
cursor: pointer;
}
.hasSelect{
background: #FFFFFF;
}
}
.address-select{
425px;
margin: 0;
padding: 5px 10px;
overflow-y: scroll;
overflow-x: scroll;
height: 320px;
border: 1px solid #CCCCCC;
border-top: 0;
li{
height: 40px;
padding: 10px 5px;
line-height: 20px;
cursor: pointer;
}
.select-li-provice{
color: #1470cc;
cursor: default;
}
li:hover{
color: #968CFF;
}
}
}
</style>
2,引用
import addressSelect from '@/components/common/address_select'
3.注册
components: {
addressSelect
},
4.调用
<addressSelect :address-select-show="is_select_show" :left-value="-75" :top-value="41" @getAddressDetail="getAddressDetail"/>
is_select_show:控制是否显示,
left-value:距离左边的距离
top-value:顶部的距离
getAddressDetail:组件返回的参数,接受两个值,一个是返回的地址,一个是对应地址的ID,都是数组