仿照小米之家做的一個省市區三級聯動,先上代碼:
HTML:
<template> <section class="myAddress"> <section> <section class="cont" @click="choseAdd()"> <section> <span>所在地區:{{Province?Province:''}} {{City && City!== '請選擇'?City:''}} {{District && District !== '請選擇'?District:''}}</span> </section> <div style="clear: both"></div> </section> </section> <!-- 省市區三級聯動選項 --> <section class="showChose" v-show="showChose"> <section class="address"> <section class="title"> <h4>選擇您所在的地區</h4> <span @click="closeAdd()">×</span> </section> <section class="title"> <div class="area" @click="provinceSelected(0)" :class="tabIndex===0?'active':''"> {{Province?Province:'請選擇'}} </div> <div class="area" @click="citySelected(1)" :class="tabIndex===1?'active':''" v-show="Province"> {{City?City:'請選擇'}} </div> <div class="area" @click="districtSelected(2)" :class="tabIndex===2?'active':''" v-show="City && hasDistrict"> {{District?District:'請選擇'}} </div> </section> <ul> <!-- 常用城市 --> <div v-show="showProvince" class="frequentCity"> <p class="frequentCityTip" v-show="showFrequentCity">常用城市</p> <div class="frequentCityList"> <span class="cityName" v-for="(frequentCity, index) in frequentCitys" :key="'frequentCity'+index" @click="selectFrequentCity(frequentCity)">廣州</span> </div> </div> <!-- 省市區列表 --> <li class="addList" v-for="(v , k) in info" @click="getProvinceId(v.index, v.AREA_NAME, k)" v-show="showProvince" :class="v.selected ? 'active' : ''">{{v.AREA_NAME}}</li> <li class="addList" v-for="(v,k) in showCityList" @click="getCityId(v.index, v.AREA_NAME, k)" v-show="showCity" :class="v.selected ? 'active' : ''">{{v.AREA_NAME}}</li> <li class="addList" v-for="(v,k) in showDistrictList" @click="getDistrictId(v.index, v.AREA_NAME, k)" v-show="showDistrict" :class="v.selected ? 'active' : ''">{{v.AREA_NAME}}</li> </ul> </section> </section> </section> </template>
JS:
export default { name: 'address', data () { return { showChose: false, // 是否顯示省市區彈框 showProvince: true, // 顯示省份列表 showCity: false, // 顯示城市列表 showDistrict: false, // 顯示區列表 showCityList: false, // 城市數據列表 showDistrictList: false, // 區數據列表 province: 5, // 當前選擇的省份index city: 3, // 當前選擇的城市index district: 57, // 當前選擇的區index District: false, // 區名字 Province: false, // 省名字 City: false, // 城市名字 areaProvince: '', areaCity: '', areaDistrict: '', tabIndex: 0, // 當前選擇的tab下標 hasDistrict: true, // 是否有區 selected: false, // 是否選中(active) info: [], // 后台交互的省市區接口數據 frequentCitys: [], // 常用城市數據 saveCityData: [], // 存儲選擇的省市區的緩存數據 showFrequentCity: false // 是否顯示常用城市 } }, components: { }, computed: { }, created () { // 獲取省市區數據 this.getAreaData() // 從緩存讀取常用城市數據 this.frequentCitys = JSON.parse(localStorage.getItem('frequentList')) this.saveCityData = JSON.parse(localStorage.getItem('frequentList')) if (!this.frequentCitys) { this.showFrequentCity = false } else { this.showFrequentCity = true } }, mounted () { }, methods: { // 獲取省市區數據 getAreaData () { console.log('獲取省市區數據') this.$root._axios('post', 'url', {}) .then(res => { console.log('res', res.data.nodes) if (res.data.nodes.length <= 0) { console.log('網絡異常') } else { this.info = res.data.nodes } }) }, // 選擇常用城市 selectFrequentCity: function (frequentCityData) { console.log('frequentCityData', frequentCityData) }, // 點擊選擇省市區 choseAdd: function () { this.showChose = true }, // 關閉彈框 closeAdd: function () { this.showChose = false }, /* eslint-disable */ // 對選擇當前的數據,進行下一級的數據的篩選 _filter (add, name, code) { let result = [] for (let i = 0; i < add.length; i++) { if (code == add[i].index) { result = add[i][name] } } return result }, /* eslint-enable */ // 選擇省份列表 getProvinceId: function (code, input, index) { this.tabIndex = 1 this.province = code this.Province = input this.showProvince = false this.showCity = true this.showDistrict = false if (!this.City) { } else { this.City = '請選擇' } if (!this.District) { } else { this.hasDistrict = false this.District = '請選擇' } this.showCityList = this._filter(this.info, 'city', this.province) // 點擊選擇當前 /* eslint-disable */ this.info.map(a => a.selected = false) /* eslint-enable */ this.info[index].selected = true this.areaProvince = input }, // 點擊省份tab provinceSelected: function (index) { this.tabIndex = index // 選項頁面的切換 this.showProvince = true this.showCity = false this.showDistrict = false }, // 選擇城市列表 getCityId: function (code, input, index) { this.tabIndex = 2 this.city = code this.City = input this.showProvince = false this.showCity = false this.showDistrict = true this.District = '請選擇' this.showDistrictList = this._filter(this.showCityList, 'district', this.city) console.log('this.showDistrictList', this.showDistrictList) // 選擇當前添加active /* eslint-disable */ this.showCityList.map(a => a.selected = false) /* eslint-enable */ this.showCityList[index].selected = true this.areaCity = input // 判斷當前選的城市是否有地區 if (this.showDistrictList.length === 0) { this.hasDistrict = false this.showDistrict = false this.District = false this.showChose = false // 把選擇的省市放入緩存中 let selectCity = {} selectCity.province = this.Province selectCity.city = this.City selectCity.district = '' this.saveCityData.push(selectCity) localStorage.setItem('frequentList', JSON.stringify(this.saveCityData)) } else { this.hasDistrict = true this.showDistrict = true } }, // 點擊城市tab citySelected: function (index) { this.tabIndex = index this.showProvince = false this.showCity = true this.showDistrict = false }, // 選擇區列表 getDistrictId: function (code, input, index) { this.district = code this.District = input // 選擇當前添加active /* eslint-disable */ this.showDistrictList.map(a => a.selected = false) /* eslint-enable */ this.showDistrictList[index].selected = true // 選取市區選項之后關閉彈層 this.showChose = false this.areaDistrict = input // 把選擇的數據放入緩存中 let selectCity = {} selectCity.province = this.Province selectCity.city = this.City selectCity.district = this.District this.saveCityData.push(selectCity) localStorage.setItem('frequentList', JSON.stringify(this.saveCityData)) }, // 點擊區tab districtSelected: function (index) { this.tabIndex = index this.showProvince = false this.showCity = false this.showDistrict = true } } }
CSS:
.myAddress { width: 100%; background-color: white; border-top: 4px solid rgba(245, 245, 245, 1); color: #333; } .myAddress .cont { border-bottom: 1px solid rgba(245, 245, 245, 0.8); } .myAddress .cont span { display: inline-block; font-size: 0.28rem; color: #333; line-height: 0.88rem; margin-left: 0.32rem; } .myAddress .cont section { float: left; } .myAddress .cont img { float: right; width: 0.14rem; height: 0.24rem; margin: 0.32rem 0.32rem 0.32rem 0; } .showChose { width: 100%; height: 100%; position: fixed; top: 0; left: 0; z-index: 120; background: rgba(77, 82, 113, 0.8); } .address { position: absolute; bottom: 0; left: 0; z-index: 121; background: #fff; width: 100%; } .title h4 { display: inline-block; margin-left: 2rem; font-size: 0.32rem; line-height: 0.88rem; font-weight: normal; color: #999; } .title span { margin: 0.42rem 0 0 2.2rem; font-size: 0.45rem; line-height: 0.34rem; color: #D8D8D8; } .area { display: inline-block; font-size: 0.24rem; line-height: 0.88rem; margin-left: 0.42rem; color: #333; } .addList { padding-left: 0.32rem; font-size: 0.34rem; line-height: 0.88rem; color: #333; } /* 修改的格式 */ .address ul { height: 6.4rem; margin-left: 5%; max-height: 6.4rem; overflow: auto; } .address .title .active { color: #0071B8; border-bottom: 0.02rem solid #0071B8; } .address ul .active { color: #0071B8; } .frequentCity{ width: 100%; } .frequentCityTip{ text-align: left;font-size: 0.3rem;margin: 0.3rem;font-weight: bold; } .frequentCityList{ display: -webkit-box; /* Chrome 4+, Safari 3.1, iOS Safari 3.2+ */ display: -moz-box; /* Firefox 17- */ display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */ display: -moz-flex; /* Firefox 18+ */ display: -ms-flexbox; /* IE 10 */ display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */ flex-wrap: wrap;margin-right: 5%;margin-left: 5%; } .cityName{ letter-spacing: 0.06rem;margin: 0.1rem 0.1rem 0.3rem 0.6rem;font-size: 0.29rem; }
邏輯分析:首先調用接口,獲取省市區數據,然后對省市區數據進行拆分。
具體分析,后面更新
這個是調用接口返回的數據其中一些,具體的參數還可以根據需求再添加。
info: [
{ index: 1, AREA_NAME: '北京', city: [
{ index: 1, AREA_NAME: '北京市', district: [
{ index: 1, AREA_NAME: '東城區' },
{ index: 2, AREA_NAME: '西城區' },
{ index: 3, AREA_NAME: '崇文區' }
] }
] },
{ index: 2, AREA_NAME: '河北', city: [
{ index: 2, AREA_NAME: '石家庄市', district: [
{ index: 4, AREA_NAME: '長安區' },
{ index: 5, AREA_NAME: '橋東區' },
{ index: 6, AREA_NAME: '橋西區' }
] },
{ index: 3, AREA_NAME: '唐山市', district: [
{ index: 7, AREA_NAME: '路南區' },
{ index: 8, AREA_NAME: '路北區' },
{ index: 9, AREA_NAME: '古冶區' }
] }
]
