效果
技术栈
vue3
代码
1. html
<div id="app">
<div class="page-wrapper">
<div class="page-main-wrapper">
<h2>省市区联动--级联简洁版</h2>
<div class="wrap" @mouseenter="showSelect=true" @mouseleave="showSelect=false">
<div class="input-box" v-text="userSelectAddress"></div>
<div v-if="showSelect" class="select-box">
<div class="select-box-inner">
<div class="select-res flex-box">
<a v-text="query.pro || '请选择省份'" @click="changePro"></a>
<a v-text="query.city || '请选择城市'" v-if="query.pro" @click="changeCity"></a>
<a v-text="query.area || '请选择区域'" v-if="query.city" @click="changeArea"></a>
</div>
<!-- 省 -->
<ul class="list-con flex-box pro-list-con" v-show="isListShow==1">
<li v-for="item in proList" v-text="item.province" @click="choosePro(item)"></li>
</ul>
<!-- 市 -->
<ul class="list-con flex-box city-list-con" v-show="isListShow==2">
<li v-for="item in cityList" v-text="item.name" @click="chooseCity(item)"></li>
</ul>
<!-- 区 -->
<ul class="list-con flex-box area-list-con" v-show="isListShow==3">
<li v-for="item in areaList" v-text="item.area" @click="chooseArea(item)"></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
2. js
Vue.createApp({
setup() {
let query = ref({
pro: '',
city: '',
area: ''
})
let userSelectAddress = ref('')
let proList = ref([])
let cityList = ref([])
let areaList = ref([])
let isListShow = ref(0)
let showSelect = ref(false)
const getPro = () => {
if (!proList.value.length) {
axiosGet("http://rap2api.taobao.org/app/mock/data/1836980", {}, (res) => {
proList.value = res.data.provList
isListShow.value = 1
})
}
}
const getCity = () => {
axiosGet("http://rap2api.taobao.org/app/mock/data/1837157", {
pro: query.value.pro
}, (res) => {
cityList.value = res.data.list
console.log(cityList.value);
})
}
const getArea = () => {
axiosGet("http://rap2api.taobao.org/app/mock/data/1839616", {
pro: query.value.pro,
city: query.value.city
}, (res) => {
areaList.value = res.data.areaList
})
}
const choosePro = (item) => {
query.value.pro = item.province
isListShow.value = 2
userSelectAddress.value = `${query.value.pro}`
getCity()
}
const chooseCity = (item) => {
query.value.city = item.name
isListShow.value = 3
userSelectAddress.value = `${query.value.pro}/${query.value.city}`
getArea()
}
const chooseArea = (item) => {
query.value.area = item.area
userSelectAddress.value = `${query.value.pro}/${query.value.city}/${query.value.area}`
}
const changePro = () => {
isListShow.value = 1
query.value.pro = ''
query.value.city = ''
query.value.area = ''
userSelectAddress.value = ''
}
const changeCity = () => {
isListShow.value = 2
query.value.city = ''
query.value.area = ''
userSelectAddress.value = `${query.value.pro}`
}
const changeArea = () => {
isListShow.value = 3
query.value.area = ''
userSelectAddress.value = `${query.value.pro}/${query.value.city}`
}
getPro()
return {
showSelect,
proList,
cityList,
areaList,
query,
choosePro,
chooseCity,
chooseArea,
userSelectAddress,
isListShow,
changePro,
changeCity,
changeArea
}
}
})
.use(ElementPlus)
.mount("#app");
3. css
.page-main-wrapper {
position: relative;
width: 500px;
margin: 50px auto;
}
.page-main-wrapper h2 {
margin-bottom: 16px;
}
.input-box {
width: 350px;
height: 50px;
border-radius: 8px;
border: 1px solid #84c3bc;
cursor: pointer;
line-height: 50px;
text-indent: 12px;
}
.select-box {
position: absolute;
padding-top: 16px;
}
.select-box-inner {
width: 350px;
height: 300px;
border: 1px solid darkgray;
border-radius: 8px;
padding: 5px;
overflow: auto;
}
.list-con {
flex-wrap: wrap;
flex-direction: column;
}
.list-con li {
width: 100%;
margin: 5px 0;
cursor: pointer;
}
.select-res {
padding: 5px;
background-color: #7ec5ad;
}
.select-res a {
padding: 0 8px;
border-right: 1px solid #a3a09b;
}
.select-res a:last-of-type {
border-right: 0;
}