最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue實現(xiàn)城市列表選擇功能

 更新時間:2018年07月16日 11:32:06   作者:小周sri的碼農(nóng)  
這篇文章主要介紹了vue實現(xiàn)城市列表選擇功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

成果展示

最后的成果就是下面所展示的內(nèi)容,因為gif圖沒有做,只能截圖所展示,接下來,會帶著大家一步一步的完成下面功能,腳手架搭建和node安裝在本次案例不會講解,如果了解,可以在我的博客園找到有詳細介紹

準備工作:

 引入axios插件,調(diào)用better-scroll第三方插件,本地json文件,可以參考目錄中的city.json,有條件的也可以自己去扒

功能分析

1.獲取json數(shù)據(jù)展示城市列表 。

2.側(cè)邊字母定位滾動到相應的位置。

3.實現(xiàn)搜索城市

接下來我們開始對組件進行劃分:本次案例中,總共劃分為五個組件,下面就是組件的劃分圖

創(chuàng)建city組件,通過父組件獲取數(shù)據(jù),傳遞給子組件

<template>
 <div class="city">
  <CityHeader></CityHeader> //頭部
  <Search :list="cities"></Search> //搜索
  <List :hot="hotCity" :letter="letter" :list="cities"></List> //城市列表
  <Alphabet @chang="handleLetterChang" :list="cities"></Alphabet> //A-Z
 </div>
</template>
<script>
import axios from 'axios'
import CityHeader from './components/Header'
import Search from './components/Search'
import List from './components/List'
import Alphabet from './components/Alphabet'
export default {
 data () {
  return {
   cities:{}, // 城市列表
   hotCity:[], //熱門城市
   letter: '' // A-Z
  }
 },
 components: {
  CityHeader,
  Search,
  List,
  Alphabet
 },
 methods:{
  getCityInfo () {
   axios.get('/api/city.json').then(this.getCityInfoSucc)
  },
  getCityInfoSucc(res){
    res = res.data
   if (res.ret && res.data) {
    const data = res.data
    this.hotCity = data.hotCities
    this.cities = data.cities
   }
   console.log(this.cities)
  },
  handleLetterChang(letter) { //接受子組件傳過來的
//   console.log(letter)
   this.letter = letter
  }
 },
 mounted () {
  this.getCityInfo ()
 }
}
</script>
<style scoped lang="stylus">
</style>

把得到的數(shù)據(jù)分次傳遞個對應的子組件,這樣有利于網(wǎng)站優(yōu)化,不用頻繁的請數(shù)據(jù)

<template>
 <div class="city">
  <CityHeader></CityHeader>
  <Search :list="cities"></Search>
  <List :hot="hotCity" :letter="letter" :list="cities"></List>
  <Alphabet @chang="handleLetterChang" :list="cities"></Alphabet>
 </div>
</template>
export default {
 data () {
  return {
   cities:{}, // 城市列表
   hotCity:[], //熱門城市
   letter: '' // A-Z
  }
 },
 components: {
  CityHeader,
  Search,
  List,
  Alphabet
 },
 methods:{
  getCityInfo () {
   axios.get('/api/city.json').then(this.getCityInfoSucc) //請求本地配置的mock數(shù)據(jù)
  },
  getCityInfoSucc(res){
    res = res.data
   if (res.ret && res.data) {
    const data = res.data
    this.hotCity = data.hotCities
    this.cities = data.cities
   }
  }
 },
 mounted () {
  this.getCityInfo ()
 }
}

創(chuàng)建頭部組件,

<template>
 <div class="header">
  城市選擇
  <router-link to="/">
   <div class="iconfont back-icon">&#xe624;</div>
  </router-link>
 </div>
</template>
<script>
export default {
}
</script>
<style scoped lang="stylus">
@import '~styles/varibles.styl';
@import '~styles/mixins.styl';
.header
 overflow: hidden
 height $headerHeight
 line-height: $headerHeight
 text-align: center
 color: #fff
 background: $bgColor
 font-size: .4rem
 .back-icon
  position: absolute
  left: 0
  top: 0
  width: .64rem
  font-size: .4rem
  text-align: center
  color: #fff
</style>

創(chuàng)建搜索組件頁面,接受父組件傳遞的數(shù)據(jù),引入better-scroll第三方插件,實現(xiàn)列表滾動

<template>
 <div>
  <div class="search">
   <input v-model="keyword" class="search-input" type="text" placeholder="輸入城市名或者拼音" />
  </div>
  <div class="search-content" ref="search" v-show="keyword">
   <ul>
    <li class="serach-item border-bottom" v-for="item in listItem" :key="item.id">{{item.name}}</li>
    <li v-show="hasNoData" class="serach-item border-bottom">沒有搜索到匹配的數(shù)據(jù)</li>
   </ul>
  </div>
 </div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
 props: {
   list: Object,
 },
 data() {
  return {
   keyword:'',
   listItem:[],
   timer:null
  }
 },
 computed: {
  hasNoData() {
   return !this.listItem.length //沒有搜索的條件是否顯示
  }
 },
 watch: {
  keyword () {
   if (this.timer) {
    clearTimeout(this.timer)
   }
   if(!this.keyword) { //清空
    this.listItem = ""
    return
   }
   this.timer = setTimeout(() => {
    const result = []
    for (let i in this.list) {
     this.list[i].forEach((value) => { //匹配搜索的條件
      if (value.spell.indexOf(this.keyword) > -1 || value.name.indexOf(this.keyword) > -1) {
       result.push(value)
      }
     })
    }
    this.listItem= result
   },100)
  }
 },
 mounted () {
  this.scroll = new BScroll(this.$refs.search)
 }
}
</script>
<style scoped lang="stylus">
@import '~styles/varibles.styl'
@import '~styles/mixins.styl'
.search
 height: .72rem
 padding: 0 .1rem
 background:$bgColor
 .search-input
  box-sizing: border-box
  width:100%
  height: .62rem
  line-height: .62rem
  text-align: center
  border-radius: .06rem
  padding: 0 .1rem
  color: #666
.search-content 
 z-index: 1
 overflow:hidden
 position:absolute
 top: 1.58rem
 left: 0
 right: 0
 bottom: 0
 background: #eee
 .serach-item
  line-height: .62rem
  padding-left:.2rem
  color:#666
  background: #fff
</style>

創(chuàng)建城市列表組件,引入better-scroll插件,實現(xiàn)列表滾動,通過watch監(jiān)聽letter,實現(xiàn)字母與城市列表滾動

<template>
 <div class="list" ref="wrapper">
  <div>
   <div class="area">
    <div class="title border-topbottom">當前城市</div>
    <div class="button-list">
     <div class="button-wrapper">
      <div class="button">鄭州</div>
     </div>
    </div>
   </div>
   <div class="area">
    <div class="title border-topbottom">熱門城市</div>
    <div class="button-list">
     <div class="button-wrapper" v-for="item in hot" :key="item.id">
      <div class="button">{{item.name}}</div>
     </div>
    </div>
   </div>
   <div class="area" 
    v-for="(item,key) in list" 
    :ref="key"
    :key="key">
    <div class="title border-topbottom">{{key}}</div>
    <ul class="item-list">
     <li class="item border-bottom"
       v-for="listInner in item"
       :key="listInner.id"
     >{{listInner.name}}</li>
    </ul>
   </div>
  </div>
 </div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
 props: {
   hot: Array,
   list: Object,
   letter:String
  },
 mounted () {
  this.scroll = new BScroll(this.$refs.wrapper)
 },
 watch:{
  letter () { //監(jiān)聽列表滾動事件 A-Z
   if(this.letter) {
    const element = this.$refs[this.letter][0]
    this.scroll.scrollToElement(element)
   }
  }
 }
}
</script>
<style scoped lang="stylus">
@import '~styles/varibles.styl';
@import '~styles/mixins.styl';
.border-topbottom
 &:before
  background: #ccc
 &:after
  background:#ccc
.border-bottom
 &:before
  background: #ccc
.list
 overflow: hidden
 position:absolute
 top:1.58rem
 left:0
 right:0
 bottom:0
 .title
  line-height: .54rem;
  background: #eee;
  padding-left: .2rem;
  color: #666;
  font-size: .26rem;
 .button-list
  overflow:hidden
  padding: .1rem .6rem .1rem .1rem
  .button-wrapper
   float:left
   width:33.33%
   .button
    margin: .1rem
    padding: .1rem 0
    text-align: center
    border: .02rem solid #ccc
    border-radius: .06rem
 .item-list
  .item
   line-height: .76rem
   color:#212121
   padding-left: .2rem
   font-size: .28rem
   text-overflow: ellipsis
   white-space: nowrap
</style>

創(chuàng)建字母組件,點擊字母,左邊列表城市想對應,通過this.$emit事件,子組件在觸發(fā)的事件傳遞給父組件,父組件通過子組件傳遞的事件,在傳遞給List組件,

<template>
 <div class="list">
  <li class="item"
   :ref="item"
    @click="handeClick" 
    @touchstart="handleTouchStart" 
    @touchmove="handleTouchMove" 
    @touchend= "handleTouchEnd"
    v-for="item of letter" 
    :key="item">{{item}}</li>
 </div>
</template>
<script>
export default {
 props: {
   list: Object
 },
 data () {
  return {
   touchstart:false,
   startY:0,
   timer: null
  }
 },
 updated () {
  this.startY = this.$refs['A'][0].offsetTop
 },
 computed: {
  letter () {
   const letter =[]
   for (let i in this.list) { //循環(huán)A-Z
    letter.push(i)
   }
   return letter
  }
 },
 methods: {
  handeClick(e) {
   this.$emit('chang',e.target.innerText) //傳給父組件City
  },
  handleTouchStart () {
   // 手指放上
   this.touchstart = true
  },
  handleTouchMove (e) {
   // 手指移動
   if(this.touchstart) {
    if(this.timer) {
     clearInterval(this.timer)
    }
    this.timer = setTimeout(() => {
     const touchY = e.touches[0].clientY -79 //到藍色頭部的距離
     const index = Math.floor((touchY - this.startY ) / 20)
     if(index >=0 && index < this.letter.length) {
      this.$emit('chang',this.letter[index])
     }
    },16)
   }
  },
  handleTouchEnd () {
   // 手指離開
   this.touchstart = false
  }
 }
}
</script>
<style scoped lang="stylus">
@import '~styles/varibles.styl';
@import '~styles/mixins.styl';
.list
 display: flex
 flex-direction:column
 justify-content: center
 position:absolute
 top: 1.58rem
 right: 0
 bottom: 0
 width: .4rem
 .item
  line-height:.44rem
  text-align: center
  color: $bgColor
  list-style:none
</style>

總結(jié)

以上所述是小編給大家介紹的vue實現(xiàn)城市列表選擇功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 手拉手教你如何處理vue項目中的錯誤

    手拉手教你如何處理vue項目中的錯誤

    在項目開發(fā)中經(jīng)常遇到各種報錯,每次總是通過這樣或那樣的辦法解決掉,這篇文章主要給大家介紹了關(guān)于如何處理vue項目中錯誤的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Vue中bus的使用詳解

    Vue中bus的使用詳解

    這篇文章主要介紹了Vue中bus的使用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法

    Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法

    這篇文章主要介紹了Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法,分析常用的一些生命周期鉤子和監(jiān)聽器可以幫助我們在組件中處理數(shù)據(jù)加載、狀態(tài)變化和響應式更新,需要的朋友可以參考下
    2024-07-07
  • Ant Design Vue Pro動態(tài)路由加載,服務器重啟首頁白屏問題

    Ant Design Vue Pro動態(tài)路由加載,服務器重啟首頁白屏問題

    這篇文章主要介紹了Ant Design Vue Pro動態(tài)路由加載,服務器重啟首頁白屏問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue中@change、@input和@blur的區(qū)別及@keyup介紹

    Vue中@change、@input和@blur的區(qū)別及@keyup介紹

    這篇文章主要給大家介紹了關(guān)于Vue中@change、@input和@blur的區(qū)別及@keyup介紹的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-02-02
  • vant的picker的坑及解決

    vant的picker的坑及解決

    這篇文章主要介紹了vant的picker的坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue實現(xiàn)權(quán)限控制路由(vue-router 動態(tài)添加路由)

    vue實現(xiàn)權(quán)限控制路由(vue-router 動態(tài)添加路由)

    今天小編就為大家分享一篇vue實現(xiàn)權(quán)限控制路由(vue-router 動態(tài)添加路由),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • Vue axios獲取token臨時令牌封裝案例

    Vue axios獲取token臨時令牌封裝案例

    這篇文章主要介紹了Vue axios獲取token臨時令牌封裝案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 如何在Vue中使用debouce防抖函數(shù)

    如何在Vue中使用debouce防抖函數(shù)

    本文主要介紹在Vue中使用debouce防抖函數(shù),設置一個門檻值,表示兩次?Ajax?通信的最小間隔時間。如果在間隔時間內(nèi),發(fā)生新的keydown事件,則不觸發(fā)?Ajax?通信,并且重新開始計時。如果過了指定時間,沒有發(fā)生新的keydown事件再將數(shù)據(jù)發(fā)送出去,這便是debouce防抖函數(shù)
    2021-12-12
  • vue項目在webpack2實現(xiàn)移動端字體自適配功能

    vue項目在webpack2實現(xiàn)移動端字體自適配功能

    這篇文章主要介紹了vue項目在webpack2實現(xiàn)移動端字體自適配的相關(guān)知識,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06

最新評論

屯留县| 堆龙德庆县| 炉霍县| 华亭县| 天长市| 万源市| 黄骅市| 霍城县| 革吉县| 建湖县| 旅游| 兴国县| 金平| 西林县| 永胜县| 平原县| 镇原县| 那曲县| 马边| 杨浦区| 凯里市| 沂南县| 米林县| 尉氏县| 大港区| 会泽县| 松潘县| 余庆县| 泰州市| 隆昌县| 齐齐哈尔市| 长乐市| 白玉县| 剑阁县| 乳源| 丽江市| 新平| 灵丘县| 濮阳县| 万源市| 永顺县|