1. 程式人生 > >vue省市區三級聯動(高仿京東)

vue省市區三級聯動(高仿京東)

destroy 傳參 sla solid 列表 git type tom ott

該栗子是我直接從公司的項目單獨拉出來的(懶得重新寫一次了),所以代碼會有些冗余,下面直接看效果:

技術分享圖片

接著上代碼:

html:

<template>
  <div>
    <div class="ysc-header">
        <p class="header-title">{{headerTxt}}</p>
    </div>
    <div class="addAddress" @click="choseAdd()">
        <input type="text" placeholder="
所在地區" class="txtmangth" disabled="disabled" v-model="userAddress"> </div> <!-- 收貨地址三級聯動選項 start--> <section class="address" :class="{toggHeight:istoggHeight}"> <section class="title"> <div class="area" @click="provinceSelected()" :class="[oneac ? ‘accolor‘ : ‘‘]
">{{Province?Province:請選擇}}</div> <div class="area" @click="citySelected()" :class="[twoac ? ‘accolor‘:‘‘]" v-show="twoshow">{{City?City:請選擇}}</div> <div class="area" @click="districtSelected()" :class="threeac ? ‘accolor‘:‘‘" v-show="threeshow">{{District?District:
請選擇}}</div> <div class="determine" v-show="showDeter" @click="determine()">確定</div> </section> <ul v-show="showProvince" class="proJuli"> <li class="addList" v-for="(v,k) in info" @click="getProvinceId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li> </ul> <ul v-show="showCity" class="citJuli"> <li class="addList" v-for="(v,k) in showCityList" @click="getCityId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li> </ul> <ul v-show="showDistrict" class="disJuli"> <li class="addList" v-for="(v,k) in showDistrictList" @click="getDistrictId(v.id, v.name, k)" :key="v.id" :class="{active : v.selected}"><span>{{v.name}}</span></li> </ul> </section> <!-- 收貨地址三級聯動選項 end--> <div class="layout" :class="{layoutBg:islayout}" @click="closeAdd()"></div> </div> </template>

script:

<script>
import maps from ../../static/js/map.js
export default {
  data () {
    return {
      islayout: false,
      istoggHeight: false,
      headerTxt: 添加新地址,
      isBc: false, // 用於控制保存按鈕高亮
      toggle: false, // 用於切換默認地址
      showDeter: false,
      oneac: true,
      twoac: false,
      threeac: false,
      twoshow: false,
      threeshow: false,
      userAddress: ‘‘,
      oneliIndex: ‘‘, // 用於高亮子菜單
      twoliIndex: ‘‘,
      titleIndex: Number,
      showProvince: true, // 第一個li默認顯示
      showCity: false, // 第二個li默認隱藏
      showDistrict: false, // 第三個li默認隱藏
      showCityList: [],
      showDistrictList: [],
      province: ‘‘,
      city: ‘‘,
      district: ‘‘,
      GetProvinceId: 2,
      District: ‘‘,
      Province: ‘‘,
      City: ‘‘,
      // v-for循環判斷是否為當前
      selected: true,
      info: maps.map // 三級聯動城市列表
    }
  },
  mounted () {
    document.querySelector(body).style.backgroundColor = #f5f7fa
  },
  created () {
    if (this.$route.query.data !== undefined) { // 如果是點擊編輯地址過來,則執行...當然了,不一定非要用路由傳參的方式,你也可以用本地存儲,反正能證明你是點擊了編輯地址過來就好
      this.showDeter = true
      this.headerTxt = 編輯收貨地址

      let editDate = JSON.parse(this.$route.query.data)
      this.province = editDate.province
      this.city = editDate.city
      this.district = editDate.district
      address.getAddressData({}).then((res) => { // axios請求,目的獲取新增地址時,保存的地址ID,用於高亮顯示
        if (res.isSuccess === 1) {
          // 初始化頁面,如果是編輯地址的話,則
          this.twoshow = true // 控制第二個nav顯示
          this.threeshow = true // 給第三個nav顯示
          this.Province = editDate.areaDescription.split( )[0]
          this.City = editDate.areaDescription.split( )[1]
          this.District = editDate.areaDescription.split( )[2]
          this.showCityList = this._filter(this.info, city, editDate.province) // editDate.province由後臺獲取的id
          this.showDistrictList = this._filter(this.showCityList, district, editDate.city) // editDate.city由後臺獲取的id
          // 高亮後臺返回選中的地址,需要對應id
          this._newArr(this.info, editDate.province)
          this._newArr(this.showCityList, editDate.city)
          this._newArr(this.showDistrictList, editDate.district)
        }
      })
    } else {
    //   address.getAddressData({}).then((res) => {
    //     if (res.isSuccess === 1) {
    //       this.info = res.resData[0].regionalInformation
    //     }
    //   })
        console.log(111)
    }
  },
  methods: {
    choseAdd: function () { // 選擇地址彈層,打開彈層
      this.islayout = true
      this.istoggHeight = true
      if (this.$route.query.data !== undefined) {
        this._gotoTop(.proJuli, 0)
      }
    },
    closeAdd: function () { // 關閉彈層
      this.istoggHeight = false
      this.islayout = false
    },
    determine () {
      this.istoggHeight = false
      this.islayout = false
      // this.showDeter = false
      this.userAddress = this.Province +   + this.City +   + this.District
    },
    _newArr (arr, selectid) {
      for (var i = 0; i < arr.length; i++) {
        if (arr[i].id === selectid) {
          this.$set(arr[i], selected, true)
        } else if (selectid === -1) {
          this.$set(arr[i], selected, false)
        }
      }
      return arr
    },
    _filter (add, name, code) { // 數組,對應數組內容,對應數組id
      let result = []
      for (let i = 0; i < add.length; i++) {
        if (code === add[i].id) {
          // console.log(code, add[i].id)
          result = add[i][name]
        }
      }
      return result
    },
    _gotoTop (info, index) { // 滾動距離 --> 對應class,第幾個index
      let proJuliBox = document.querySelector(info)
      let activeBox = document.getElementsByClassName(active)[index]
      let t = activeBox.offsetTop - 67 + 20 // 後面的數據,根據頁面情況自己調整
      proJuliBox.scrollTo(0, t)
    },
    getProvinceId: function (code, input, index) { // 點擊第一個li
      // console.log(‘code‘, code, input, index)
      this.titleIndex = Number
      this.province = code
      this.Province = input // 獲取選中的省份
      this.showProvince = false
      this.showCity = true
      this.showDistrict = false
      this.showCityList = this._filter(this.info, city, this.province)
      // 點擊選擇當前
      this.info.map(a => { a.selected = false })
      this.info[index].selected = true
      // console.log(this.info[index].name) // 點擊的省份的名字

      this.oneac = false // 給第一個nav去掉高亮
      this.twoac = true // 給第二個nav添加高亮
      this.threeac = false // 去除第三個li的高亮
      this.twoshow = true // 控制第二個nav顯示
      // this.City = false // 清除市級和區級nav選項
      // this.District = false // 清除市級和區級nav選項
      this.City = ‘‘ // 第二nav置空
      this.threeshow = false // 第三nav隱藏
      this.oneliIndex = index
      this._newArr(this.showCityList, -1) // 清除市級高亮
      this.showDeter = false
    },
    provinceSelected: function () {
      // console.log(‘點擊了第一個nav‘)
      // this.titleIndex = 1
      // 清除市級和區級列表
      // this.showCityList = true
      // this.showDistrictList = true
      // 清除市級和區級nav選項
      // this.City = false
      // this.District = false
      // 選項頁面的切換
      this.showProvince = true
      this.showCity = false
      this.showDistrict = false
      this.oneac = true // 給第一個nav添加高亮
      this.twoac = false // 給第二個nav去除高亮
      this.threeac = false // 給第三個nav去掉高亮
    },
    getCityId: function (code, input, index) { // 點擊第二個li
      // console.log(‘id‘, code, input, ‘index‘, index)
      this.titleIndex = Number
      this.city = code
      this.City = input
      this.showProvince = false
      this.showCity = false
      this.showDistrict = true
      this.showDistrictList = this._filter(this.showCityList, district, this.city)
      // 選擇當前添加active
      this.showCityList.map(a => { a.selected = false })
      this.showCityList[index].selected = true
      this.twoliIndex = index

      this.twoac = false // 給第二個nav去除高亮
      this.threeac = true // 給第三個nav添加高亮
      this.threeshow = true // 給第三個nav顯示
      this.District = ‘‘ // 第三nav置空
      this._newArr(this.showDistrictList, -1) // 清除區級高亮
      this.showDeter = false
    },
    citySelected: function () {
      // console.log(‘點擊了第二個nav‘)
      this.titleIndex = 2
      this.showProvince = false
      this.showCity = true
      this.showDistrict = false

      this.oneac = false // 給第一個nav去掉高亮
      this.twoac = true // 給第二個nav添加高亮
      this.threeac = false // 給第三個nav去掉高亮
      if (this.$route.query.data !== undefined) {
        this.$nextTick(() => { // 讓li標簽回到頂部
          this._gotoTop(.citJuli, 1)
        })
      }
    },
    getDistrictId: function (code, input, index) {
      this.titleIndex = Number
      this.district = code
      this.District = input
      // 選擇當前添加active
      this.showDistrictList.map(a => { a.selected = false })
      this.showDistrictList[index].selected = true
      // 選取市區選項之後關閉彈層

      this.oneac = false // 給第一個nav去掉高亮
      this.showDeter = true
    },
    districtSelected: function () { // 第三個選擇
      // console.log(‘點擊了第三個nav‘)
      this.showProvince = false
      this.showCity = false
      this.showDistrict = true

      this.oneac = false // 給第一個nav去掉高亮
      this.twoac = false // 給第二個nav去掉高亮
      this.threeac = true // 給第三個nav添加高亮
      if (this.$route.query.data !== undefined) {
        this.$nextTick(() => { // 讓li標簽回到頂部
          this._gotoTop(.disJuli, 2)
        })
      }
    }
  },
  beforeDestroy () {
    document.querySelector(body).style.backgroundColor = #fff
  }
}
</script>

style:

</script>
<style>
*{
  margin: 0;
  padding: 0;
}
.ysc-header{
  font-size: .28rem;
  text-align: center;
}
.addAddress input {
  height: 0.8rem;
  width: 83%;
  background: #fff;
  color: #262e31;
  font-size: .3rem;
  border: none;
  margin: 0 .3rem;
  padding: 0 .3rem;
}
/* 地址選擇彈層 */
.ac{
  color: #000!important;
  border-bottom: 0.02rem solid #fff!important;
}
.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 p{
  display: inline-block;
  font-size: 0.28rem;
  color: #333333;
  line-height: 0.88rem;
  margin-left: 1rem;
}
.myAddress .cont .pic2{
  float: right;
  width: 0.14rem;
  height: 0.24rem;
  margin: 0.32rem 0.32rem 0.32rem 0;
}
.myAddress .cont p.text{
  margin-left: 0.72rem;
}
.address{
  position:absolute;
  bottom:0;
  left:0;
  z-index:121;
  background:#fff;
  width:100%;
  height: 0;
  overflow: hidden;
  transition: height .5s;
}
.toggHeight{
  height: 7.7rem;
}
.layout{
  width:100%;
  height:100%;
  position:fixed;
  top:0;
  left:0;
  z-index:120;
  opacity: 0;
  transition: all .5s;
  background:rgb(53, 58, 60);
  visibility: hidden;
}
.layoutBg{
  opacity: .7;
  visibility: visible;
}
.area{
  float: left;
  display:inline-block;
  font-size:0.24rem;
  height: .48rem;
  line-height:.48rem;
  margin-left:0.42rem;
  color:#262e31;
  margin-top: .31rem;
  max-width: calc(100% - 80%);overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}
.addList{
  margin-left: .4rem;
  font-size:0.3rem;
  line-height:0.67rem;
  color:#262e31;
}
.address ul{
  height: calc(100% - .82rem);
  overflow:auto;
}
.address ul li{
  list-style: none;
}
.address .title .accolor{
  color: #d2a24e;
  border-bottom:0.04rem solid #d2a24e;
}
.address ul .active{
  color:#d2a24e;
}
.address ul .active span::after{
  content: ‘‘;
  background-image: url(../assets/images/gou_img.png);
  width: .4rem;
  height: .2rem;
  background-repeat: no-repeat;
  background-size: .2rem .13rem;
  background-position: left .16rem center;
  display: inline-block;
}
.title{
  height: .82rem;
  border-bottom: .01rem solid #8a96a3;
}
.determine{
  display: inline-block;
  width: .75rem;
  text-align: center;
  float: right;
  height: .82rem;
  line-height: .82rem;
  margin-right: .3rem;
  color: #d2a24e;
  font-size: .28rem;
}
</style>

PS:那個地址的JS文件由於太大我就不貼出來了,大家可以去我的github那裏下載完整的demo(覺得這個栗子還不錯的話,記得給個star哦,麽麽噠),裏面有---->https://github.com/yy-biboy/sanjiliandongDemo

vue省市區三級聯動(高仿京東)