兄弟组件之间的联动
在本节中,我们将要实现点击右侧的Alphabet,左侧List组件可以移动到指定的位置,实现兄弟组件之间的通信,我们可以借助它们公共的父组件实现转发。具体步骤如下:
1、步骤一:兄弟组件1发送change,并传入参数e.target.innerText,而后需要在父组件City中监听该事件;
// Alphabet组件
<template>
<ul class="list">
<!--对象的循环遍历-->
<li
class="item"
v-for="(city, key) of cities"
:key="key"
:ref="key"
@click="handleLetterClick"
@touchStart="handleTouchStart"
@touchMove="handleTouchMove"
@touchEnd="handleTouchEnd"
>
{{key}}
</li>
</ul>
</template>
// Alphabet组件
// 实现Alphabet组件与List非父子组件之间的通信,需要父组件转为两者中转方
handleLetterClick(e){
console.log(e.target.innerText);
// 步骤一:兄弟组件1发送change,并传入参数e.target.innerText,而后需要在父组件City中监听该事件
this.$emit('change', e.target.innerText)
}
2、步骤二:City组件监听change事件,绑定方法;
3、步骤三:接收参数letter,转化给List组件;
4、步骤四:letter传递给List;
// City组件
<template>
<div>
<city-header></city-header>
<city-search></city-search>
<!--步骤四:letter传递给List-->
<city-list :cities="cities" :hotCities="hotCities" :letter="letter"></city-list>
<!--步骤二:City组件监听change事件,绑定方法-->
<city-alphabet :cities="cities" @change="handleLetterChange"></city-alphabet>
</div>
</template>
// City组件
// 步骤三:接收参数letter,转化给List组件
handleLetterChange(letter){
console.log(letter);
this.letter = letter;
}
5、步骤五:接收letter;
6、步骤六:监听letter;
// list组件
props: {
cities: Object,
hotCities: Array,
// 步骤五:接收letter
letter: String
}
// 步骤六:监听letter
watch: {
letter(){
if (this.letter) {
console.log(this.$refs[this.letter]); // 注意:这个是数组而不是元素节点
const element = this.$refs[this.letter][0];
this.scroll.scrollToElement(element); // 滚动到指定的位置
}
console.log(this.letter)
}
}
此时,已经实现组件间的联动了。
触摸事件
<template>
<ul class="list">
<!--对象的循环遍历-->
<li
class="item"
v-for="(city, key) of cities"
:key="key"
:ref="key"
@click="handleLetterClick"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
>
{{key}}
</li>
</ul>
</template>
<script>
export default{
name: 'CityAlphabet',
props: {
cities: Object
},
data(){
return {
touchStatus: false
}
},
computed: {
// 创建一个数组,存储['A','B'...],用于循环
letters(){
const letters = [];
for (let i in this.cities) {
letters.push(i);
}
return letters; // ['A','B']
}
},
methods: {
// 实现Alphabet组件与List非父子组件之间的通信,需要父组件转为两者中转方
handleLetterClick(e){
console.log('您点击的字符是:',e.target.innerText);
// 步骤一:兄弟组件1发送change,并传入参数e.target.innerText,而后需要在父组件City中监听该事件
this.$emit('change', e.target.innerText)
},
handleTouchStart(){
this.touchStatus = true;
console.log('handleTouchStart');
},
handleTouchMove(e){
if (this.touchStatus) {
const startY = this.$refs['A'][0].offsetTop;
const touchY = e.touches[0].clientY - 79;
console.log(touchY);
const index = Math.floor((touchY - startY) / 20);
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index]);
}
}
},
handleTouchEnd(){
this.touchStatus = false;
}
}
}
</script>
<style scoped lang="stylus">
@import "~styles/varibles.styl"
.list
/*background red*/
position absolute
top 1.58rem
right 0
bottom 0
width 0.4rem
line-height 0.4rem
/*水平垂直居中*/
display flex
flex-direction column
justify-content center
.item
text-align center
line-height 0.4rem
color $bgColor
</style>