vue项目笔记(17)-兄弟组件之间的联动

兄弟组件之间的联动

在本节中,我们将要实现点击右侧的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>

猜你喜欢

转载自blog.csdn.net/qq_41115965/article/details/81698292