功能 通过点击右侧字母ABCD(alphabet.vue里的)等让 左侧ABCD(list.vue中的)的下的列表和左侧一一对应city.vue
<template>
<div>
<city-header></city-header>
<city-search></city-search>
<city-list :cities="cities" :hot="hotCities" :letter="letter"></city-list>
<city-alphabet
:cities="cities"
@change="handleLetterChange"
></city-alphabet>
</div>
</template>
<script>
import axios from "axios";
import CityHeader from "./components/Header";
import CitySearch from "./components/Search";
import CityList from "./components/List";
import CityAlphabet from "./components/Alphabet";
export default {
name: "City",
data() {
return {
cities: {},
hotCities: [],
letter: ""
};
},
components: {
CityHeader,
CitySearch,
CityList,
CityAlphabet
},
methods: {
getCityInfo() {
axios.get("/js/city.json").then(this.getCityInfoSucc);
},
getCityInfoSucc(res) {
res = res.data;
if (res.ret && res.data) {
const data = res.data;
this.cities = data.cities;
this.hotCities = data.hotCities;
// console.log(this.cities);
// console.log(this.hotCities);
// console.log(res);
}
},
handleLetterChange(letter) {
this.letter = letter;
}
},
mounted() {
this.getCityInfo();
}
};
</script>
<style lang="stylus" scoped></style>
list.vue
<template>
<div class="list" ref="wrapper">
<div>
<div class="area">
<div class="title border-topbottom">当前城市</div>
<div class="button-list">
<div class="button-wraper">
<div class="button">北京</div>
</div>
</div>
</div>
<div class="area">
<div class="title border-topbottom">热门城市</div>
<div class="button-list">
<div class="button-wraper" v-for="item of hot" :key="item.id">
<div class="button">{{ item.name }}</div>
</div>
</div>
</div>
<div class="area" v-for="(item, key) of cities" :key="key" :ref="key">
<div class="title border-topbottom">{{ key }}</div>
<div class="item-list" v-for="innerItem of item" :key="innerItem.id">
<div class="item border-bottom">{{ innerItem.name }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import Bscroll from "better-scroll";
export default {
name: "CityList",
props: {
cities: Object,
hot: Array,
letter: String
},
mounted() {
this.scroll = new Bscroll(this.$refs.wrapper);
},
watch: {
letter() {
if (this.letter) {
console.log(this.letter); // 能正常輸出 this.letter和v-for循環的标签的key一样
//const element = this.$refs["B"]; //輸出了一個div
const element = this.$refs[this.letter]; //報錯 undefined 取不到div數組
// this.scroll.scrollToElement(element);
console.log(element);
}
}
}
};
</script>
<style lang="stylus" scoped>
@import '~css/varibles.styl';
.border-topbottom {
&:before {
border-color: #cccccc;
}
&:after {
border-color: #cccccc;
}
}
.list {
overflow: hidden;
position: absolute;
top: 1.58rem;
left: 0;
right: 0;
bottom: 0;
.border-bottom {
&:before {
border-color: #cccccc;
}
}
.title {
line-height: 0.54rem;
background: #eee;
height: 0.44rem;
padding-left: 0.2rem;
font-size: 0.26rem;
// border-bottom .02rem solid ;
margin-top: 0.1rem;
}
.button-list {
overflow: hidden;
padding: 0.1rem 0.6rem 0.1rem 0.1rem;
.button-wraper {
float: left;
width: 33.3%;
.button {
text-align: center;
border: solid 0.02rem #cccccc;
margin: 0.1rem;
padding: 0.1rem;
border-radius: 0.06rem;
}
}
}
.item-list {
.item {
line-height: 0.76rem;
padding-left: 0.2rem;
}
}
}
</style>
alpahbet.vue
<template>
<div class="list">
<div
class="item"
v-for="(item, key) of cities"
:key="key"
@click="handleLetterClick"
>
{{ key }}
</div>
</div>
</template>
<script>
export default {
name: "CityAlpahbet",
props: {
cities: Object
},
methods: {
handleLetterClick(e) {
// console.log(e.target.innerHTML);
this.$emit("change", e.target.innerHTML);
}
}
// mounted() {
// this.scroll = new Bscroll(this.$refs.wrapper);
// }
};
</script>
<style lang="stylus" scoped>
// @import '~css/varibles.styl';
.list {
overflow hidden
display: flex;
flex-direction: column;
justify-content: center;
position: absolute;
top: -2.2rem;
right: 0;
bottom: 0;
width: 0.4rem;
// background: red;
// padding-top 1rem
.item {
line-height: 0.4rem;
text-align: center;
color: green;
}
}
</style>
alpahbet.vue
中有问题。handleLetterClick中$emit传递的参数为
e.target.innerHTML
,你以为是C,其实是'\nC\n'。这是因为你在div中写这个key的时候留有换行符,所以你需要在template中把这个换行符去掉,或者使用
e.target.innerText
。最合理的就是在点击事件中把这个key当作参数传入。