vue省市區三級聯動


仿照小米之家做的一個省市區三級聯動,先上代碼:

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: '古冶區' }
] }
]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM