Vue学习笔记-项目开发3.7兄弟组件数据传递(城市列表随字母表动)

一、功能点描述

点击选择右侧字母时左边城市列表自动滑动到对应的字母区域

二、设计方式

       兄弟组件间的数据传递,因为层级结构简单,所以采用的是子组件传递数据给父组件,然后父组件再传递数据给子组件
       1、子组件(字母表)传递给父组件(城市)

<template>
  <ul class="list">
    <li
      class="item"
      v-for="item of letters"
      :key="item"
	  //绑定click事件执行handleLetterClick函数
      @click="handleLetterClick"
    >
      {{item}}
    </li>
  </ul>
</template>
  // 其他就不写 就写这个函数
  methods: {
	//事件触发后会传递一个event对象。其中包含了点击标签的内容
    handleLetterClick (e) {
	  //发送'change'信号给父组件。带上了标签文本内容
      this.$emit('change', e.target.innerText)
    }
  }

       2、父组件(城市)传递给另外一个子组件(各城市列表)

<template>
  <div>
    <city-header></city-header>
    <city-search></city-search>
    <city-list
      :cities = "cities"
      :hot = "hotCities"
	   //3. 然后再传递给子组件
      :letter = "letter"
    ></city-list>
    <city-alphabet
      :cities="cities"
	  //1. 其他不管就这个。监听change事件,调用handleLetterChange函数
      @change="handleLetterChange"
    ></city-alphabet>
 
  </div>
</template>
 
  data () {
    return {
      cities: {},
      hotCities: [],
      letter: ''
    }
  }
	//2. 将子组件的数据复制给letter变量
    handleLetterChange (letter) {
      this.letter = letter
    }

       3、子组件(城市列表)接收传递来的数据进行跳转

  props: {
    hot: Array,
    cities: Object,
   // 1. 就这货接收数据
    letter: String
  },
  mount
  //2. 然后使用监听函数watch 监听letter的变化。一旦发生变化就滚动到对应元素的位置
  watch: {
    letter () {
      if (this.letter) {
		//4. 根据letter的值跳转到对应ref的标签对象。
        const element = this.$refs[this.letter][0]
		//5. 利用scrollToElement方法跳转到对应的元素即跳转完成
        this.scroll.scrollToElement(element)
      }
    }
  }
<div class="area"
    v-for="(item, key) of cities"
    :key="key"
    //3. 这里将标签对象与key值做绑定
    :ref="key"
>

三、手指滑动列表随动(以上功能为点动)

监听手指的变化

<template>
  <ul class="list">
    <li
      class="item"
      // 6.这里改成letters 而不是cities了(由于通过计算函数计算了城市列表)
      v-for="item of letters"
      :key="item"
      :ref="item"
	  //1. 手指开始触碰字母列表
      @touchstart="handleTouchStart"
      //2. 字母开始移动字母列表
      @touchmove="handleTouchMove"
      //3.字母离开屏幕
      @touchend="handleTouchEnd"
      //这个是前面的那个监听事件不管他
      @click="handleLetterClick"
    >
      {{item}}
    </li>
  </ul>
</template>
 
//4. 使用计算函数 给字母表生成一个数组。等下再定位字母的时候会用到
//同时 template页面也要跟着改
  computed: {
    letters () {
      const letters = []
      for (let i in this.cities) {
        letters.push(i)
      }
      return letters
    }
  },
 
 
  // 监听的函数具体实现:
  data () {
    return {
      //用来判断拇指是否接触了字母列表
      touchStatus: false
    }
  }
 
    handleTouchStart () {
      this.touchStatus = true
    },
    handleTouchMove (e) {
      if (this.touchStatus) {
		// 7. 先获取到A字母的标签与Header.vue组件下沿的距离
        const startY = this.$refs['A'][0].offsetTop
		// 8. 然后获取到拇指接触屏幕的高度减去Header.vue组件的高度 获得Header.vue组件下沿与拇指的高度 79为header.vue的高度
        const touchY = e.touches[0].clientY - 79
		// 9. 处理这两个元素的高度距离之后除以每个字母标签的高度(20)并去除小数点。 获得字母列表的所在顺序
        const index = Math.floor((touchY - startY) / 20)
		// 10. 判断字母是不是已经跑出字母表之外了
        if (index >= 0 && index < this.letters.length) {
		// 11. 将字母列表的所在顺序当做letters的下标 触发兄弟组件传递。完成
          this.$emit('change', this.letters[index])
        }
      }
    },
    handleTouchEnd () {
      this.touchStatus = false
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值