###父组件
<template>
<div>
<city-header></city-header>
<city-search></city-search>
//父组件向子组件传值通过属性绑定的方式
// @(v-on)接受子组件传递过来的值
<city-list :citys='citys' :hotCitys='hotCitys' :letter='letter'></city-list>
<city-alphabet :citys='citys' @change='handleLetterChang'></city-alphabet>
</div>
</template>
<script>
import axios from 'axios'
import CityHeader from './compontents/Header'
import CitySearch from './compontents/Search'
import CityList from './compontents/List'
import CityAlphabet from './compontents/Alphabet'
export default {
// 组件注册
components: {
CityHeader,
CitySearch,
CityList,
CityAlphabet
},
data(){
return{
citys:{},
hotCitys:[],
letter:''
}
},
mounted () {
this.getCityInfo()
},
// ajax请求
methods:{
getCityInfo (){
axios.get('api/city.json')
.then(this.handleGetCityInfo)
},
handleGetCityInfo (res){
res = res.data;
if(res.ret && res.data){
const data = res.data
this.citys = data.cities;
this.hotCitys = data.hotCities
}
},
//处理子组件传递过来的值
handleLetterChang:function(letter){
this.letter = letter;
}
}
}
</script>
<style lang="stylus" scoped>
</style>
###城市列表组件
<template>
<div class='list' ref='warpper'>
<div>
<div class="area">
<div class="title">当前城市 </div>
<div class="button-list">
<div class="button-warpper">
<div class="button">北京</div>
</div>
</div>
</div>
<div class="area">
<div class="title">热门城市 </div>
<div class="button-list">
<template v-for='item of hotCitys'>
<div class="button-warpper" :key='item.id'>
<div class="button">{{item.name}}</div>
</div>
</template>
</div>
</div>
<template v-for='(item,key) of citys' >
<div class="area" :key='key' :ref='key'>
<div class="title"> {{key}} </div>
<ul class='area-list' v-for='innerItem of item' :key='innerItem.id'>
<li class='area-li'>{{innerItem.name}}</li>
</ul>
</div>
</template>
</div>
</div>
</template>
<script>
//引入better-scroll 插件
import BScroll from 'better-scroll'
export default{
name:'CityList',
//接受父组件传递过来的值
props: {
hotCitys:Array,
citys:Object,
letter:String
},
//下拉滚动
mounted () {
this.scroll = new BScroll(this.$refs.warpper)
// console.log(this.$refs.warpper)
},
watch: {
letter () {
if(this.letter){
//点击当前的字母,自动跳转到字母所对应的的地域模块
const element = this.$refs[this.letter][0];
this.scroll.scrollToElement(element)
}
}
}
}
</script>
<style lang="stylus" scoped>
@import '~@styles/varibles.styl';
.list
overflow hidden
position absolute
top 1.78rem
bottom 0
left 0
right 0
.area
height auto
.title
line-height .5rem
background #eeeeee
padding-left 0.2rem
font-size .26rem
text-align left
border-bottom .01rem solid #1012
.button-list
overflow hidden
padding .1rem .6rem .1rem .1rem
.button-warpper
float left
width:33%
.button
margin .1rem
padding .1rem 0
text-align center
border .02rem solid #cccccc
border-radius .06rem
line-height .5rem
.area-li
line-height .76rem!important
padding-left .2rem!important
line-height .76rem
border-bottom .01rem solid #1012
text-align left
</style>
######右边字母定位
<template>
<ul class="list">
<li
v-for="item of letters"
:key="item"
:ref="item"
@click="handleLetterClick"
@touchstart.prevent="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>{{item}}</li>
</ul>
</template>
<script>
export default {
name: "Alphabet",
props: {
citys: Object
},
data() {
return {
touchStatus: false,
startY: 0,
timer: null
};
},
//当页面挂载完成,startY就不需要重新计算
updataed() {
this.startY = this.$refs["A"][0].getBoundingClientRect().top;
},
computed: {
letters() {
const letters = [];
for (let i in this.citys) {
letters.push(i);
}
return letters;
}
},
methods: {
handleLetterClick: function(e) {
this.$emit("change", e.target.innerText);
},
handleTouchStart() {
this.touchStatus = true;
},
handleTouchMove(e) {
// const length 字母之间的高度 = 手指划到的高度touchY - 第一个字母 A 距离顶部的高度 startY
// const index = length /20 总的高度除以20就是分到的等分,也就是当前的字母位置
// 通过传值的方式将当前的index传递给父组件
if (this.touchStatus) {
if(this.timer){
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
const touchY = e.touches[0].clientY;
const index = Math.floor((touchY - this.startY ) / 20);
if (index >= 0 && index < this.letters.length) {
this.$emit("change", this.letters[index]);
}
},16)
}
},
handleTouchEnd() {}
}
};
</script>
<style lang="stylus" scoped>
@import '~@styles/varibles.styl';
.list {
display: flex;
flex-direction: column;
justify-content: center;
position: fixed;
top: 50%;
right: 0;
width: 0.4rem;
transform: translate(2%, -50%);
}
.list li {
color: $bgColor;
line-height: 0.4rem;
}
</style>
网友评论