在vue项目中使用BetterScroll插件(2)-点击导航条定位

一、背景需求

在城市列表页面中,我们希望通过导航条完成以下2项功能:
1、 点击字母,定位到以该字母开头的城市区域
2、 在垂直方向拖动导航条,根据鼠标(手指)所在的字母 定位到相应区域
页面的静态布局如下图:
image.png

二、兄弟组件的数据传递

字母导航条所在的子组件为 Alphabet,城市列表所在的子组件为 List
想要通过点击字母、定位到相应区域
就需要 Alphabet 传递数据给 List
由于他们具有相同的父组件(即页面根组件)
因此我们采用子组件->父组件->子组件的路径传递数据

具体的实现思路如下:
1、为导航条绑定点击事件

// Alphabet.vue模板
<template>
  <ul class="list">
    <li class="item"
        v-for="item of letters"
        :key="item"
        :ref="item"
        @click="handleLetterClick"
    >
        {{item}}
    </li>
  </ul>
</template>

2、当导航条被点击时,向外触发change事件,并以字符串形式传递被点击的字母

  methods: {
    handleLetterClick (event) {
      this.$emit('change', event.target.innerText)
    }

3、父组件监听change事件

// 父组件模板
<template>
  <div>
    <city-header></city-header>
    <city-search></city-search>
    <city-list
      :cities="cities"
      :hotCities="hotCities"
      :letter="letter"
    ></city-list>
    <city-alphabet
      :cities="cities"
      @change="handleLetterChange"
    ></city-alphabet>
  </div>
</template>

4、当监听到change事件时,将接收的数据传递给城市列表所在的子组件

// 父组件脚本
export default {
  name: 'City',
  components: {
    CityHeader,
    CitySearch,
    CityList,
    CityAlphabet
  },
  data () {
    return {
      cities: {},
      hotCities: [],
      letter: ''
    }
  },
  methods: {
    handleLetterChange (letter) {
      this.letter = letter
    }
  }
}

5、城市列表所在的子组件接收数据,通过scrollToElement方法定位

// List子组件脚本
<script>
import BScroll from 'better-scroll'
export default {
  name: 'CityList',
  props: {
    cities: Object,
    hotCities: Array,
    letter: String
  },
  mounted () {
    this.scroll = new BScroll(this.$refs.wrapper)
  },
  watch: {
    letter () {
      if (this.letter) {
        const element = this.$refs[this.letter][0]
        this.scroll.scrollToElement(element)
      }
    }
  }
}
</script>

第二项功能的实现请参考下一篇文章

posted @ 2020-07-18 16:10  BAEBAE996  阅读(460)  评论(0编辑  收藏  举报