Vue2.5开发去哪儿网App 城市列表开发之 兄弟组件间联动及列表性能优化
一, 兄弟组件间联动
1. 点击城市字母,左侧对应显示
给遍历的 字母 添加一个点击事件:
Alphabet.vue
@click="handleLetterClick"
handleLetterClick (e) {
//获取对应的字母
this.$emit('change', e.target.innerHTML)
}
在 父组件City.vue 中,监听
<city-alphabet :cities="cities" @change="handleLetterChange"></city-alphabet>
handleLetterChange (letter) {
this.letter = letter
}
然后转发给子CityList组件:
<city-list :letter="letter"></city-list>
CityList组件,监听:
添加 ref属性 <div class="area" v-for="(city,key) in cities" :key="key" :ref="key">
<div class="title border-topbottom">{{key}}</div>
<div class="item-list">
<div class="item border-bottom" v-for="c in city" :key="c.id">{{c.name}}</div>
</div>
</div>
props: ['letter'],
watch: {
letter () {
if (this.letter) {
const element = this.$refs[this.letter][0]
// better-scrool方法,滚动区自动滚动到元素上
this.scroll.scrollToElement(element)
}
}

2. 拖动城市字母表,左侧城市对应滚动
给Alphabet.vue 字母列表绑定事件:
<ul class="list">
<li class="item" v-for="item in letters" :key="item"
@click="handleLetterClick"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
:ref = 'item'
>{{item}}
</li>
</ul>
事件说明:
touchstart : 触摸开始(手指放在触摸屏上)
touchmove : 拖动(手指在触摸屏上移动)
touchend : 触摸结束(手指从触摸屏上移开)
当前第几个字母 = (触摸处浏览器页面的垂直坐标 - A 字母距离搜索栏底部的距离) / 每个字母的高度
methods: {
handleTouchStart () {
//滑动开始
this.touchStatus = true
},
handleTouchMove (e) {
if (this.touchStatus) {
// A 字母距离搜索栏底部的距离
const startY = this.$refs['A'][0].offsetTop
// 79 为:顶部搜索栏 的高度
const touchY = e.touches[0].clientY - 79
const index = Math.floor(touchY - startY) / 20
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
}
}
},
handleTouchEnd () {
// 滑动结束
this.touchStatus = false
}
}
<template>
<div>
<ul class="list">
<li class="item" v-for="item in letters" :key="item"
@click="handleLetterClick"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
:ref = 'item'
>{{item}}
</li>
</ul>
</div>
</template> <script>
export default {
name: 'CityAlphabet',
props: ['cities'],
data () {
return {
touchStatus: false
}
},
computed: {
letters () {
const letters = []
for (let i in this.cities) {
letters.push(i)
}
return letters
}
},
methods: {
handleLetterClick (e) {
this.$emit('change', e.target.innerHTML)
},
handleTouchStart () {
this.touchStatus = true
},
handleTouchMove (e) {
if (this.touchStatus) {
// A 字母距离搜索栏底部的距离
const startY = this.$refs['A'][0].offsetTop
const touchY = e.touches[0].clientY - 79
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 lang="stylus" scoped>
@import "~styles/varibles.styl"
.list
position absolute
right 0
top 1.58rem
bottom 0
display flex
width .4rem
flex-direction column
justify-content center
.item
text-align center
line-height .4rem
color $bgColor
</style>
Alphabet.vue

二,列表切换性能优化
1. 滚动的优化
滚动重复执行运算:
this.$refs['A'][0].offsetTop
在 data 中定义 变量
data () {
return {
startY: 0
}
}
添加生命周期钩子 updated:
updated () {
this.startY = this.$refs['A'][0].offsetTop
}
handleTouchMove (e) {
if (this.touchStatus) {
const touchY = e.touches[0].clientY - 79
const index = Math.floor(touchY - this.startY) / 20
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
}
}
}
2. 节流限制 函数 handleTouchMove() 执行的频率
data中 定义 timer: null
data () {
return {
touchStatus: false,
startY: 0,
timer: null
}
函数的改动:
handleTouchMove (e) {
if (this.touchStatus) {
if (this.timer) {
clearTimeout(this.time)
}
this.timer = setTimeout(() => {
const touchY = e.touches[0].clientY - 79
const index = Math.floor(touchY - this.startY) / 20
if (index >= 0 && index < this.letters.length) {
this.$emit('change', this.letters[index])
}
}, 16)
}
}
项目地址:https://github.com/1417766861/Vue2.5-App/tree/master/Travel
Vue2.5开发去哪儿网App 城市列表开发之 兄弟组件间联动及列表性能优化的更多相关文章
- Vue2.5开发去哪儿网App 城市列表开发之 Vuex实现数据共享及高级使用
一,数据共享 1. 安装: npm install vuex --save 2. 在src目录下 新建state文件夹,新建index.js文件 3. 创建一个 store import Vue f ...
- Vue2.5开发去哪儿网App 城市列表开发
一,城市选择页面路由配置 ...
- Vue2.5开发去哪儿网App 详情页面开发
一,banner 图的设计 1. 新建detail的路由 import Detail from '@/pages/detail/Detail' ...... { path: '/detail', na ...
- Vue2.5 开发去哪儿网App
Vue2.5开发去哪儿网App 技术栈和主要框架
- Vue2.5开发去哪儿网App 从零基础入门到实战项目
第1章 课程介绍本章主要介绍课程的知识大纲,学习前提,讲授方式及预期收获. 1-1 课程简介 试看第2章 Vue 起步本章将快速讲解部分 Vue 基础语法,通过 TodoList 功能的编写,在熟悉基 ...
- Vue2.5开发去哪儿网App 第四章笔记 下
1.解决非父子组件之间的传值问题 非父子组件传值(Bus/总线/发布订阅模式/观察者模式) 给 Vue类上挂在一个属性,然后创建vue实例时,实例就拥有了这个属性 Vue.prototype.bus ...
- Vue2.5开发去哪儿网App 第四章笔记 上
一 . 组件细节知识点 1. 解决组件在h5中编码规范 例如 : table , ul , ol 等等 <table> <tbody> <row></r ...
- Vue2.5开发去哪儿网App 第二章笔记
Vue完成 TodoList 1.默认方式 <!DOCTYPE html> <html lang="en"> <head> <meta ...
- Vue2.5开发去哪儿网App 首页开发
主页划 5 个组件,即 header icon swiper recommend weekend 一. header区域开发 1. 安装 stylus npm install stylus --s ...
随机推荐
- boost-字符编码转换:使用conv
Windows下的字符集转换可以使用WideCharToMultiByte/ MultiByteToWideChar,Linux下字符集转换可以使用iconv()函数,下面为使用boost的conv来 ...
- MarkDown总结
转载自:https://www.jianshu.com/p/q81RER:做了一些部分修改: 一:总纲 1.所有的格式均要空格,如#后面加个空格,-后面加空格,1.后面加空格等等: 2.双向包裹的不能 ...
- embeded_2_separate_sync
//如果是8位的话,只选择低8位传输 //因为同步码也是可以自己设置,所以把同步码设置成parameter最好 module embeded_2_separate_sync( input clk, : ...
- python之深浅copy
深浅copy 1.赋值运算 a = [1, 2, 3] b = a a.append(666) print(b) #output:[1, 2, 3, 666] 对于赋值运算来说,a与b指向的是同一个内 ...
- 2.2.2synchronized同步代码块的使用
当两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,一段时间内只能有一个线程执行,另一个线程必须等待期执行完才能执行. package com.cky.bea ...
- 2017-12-24 自定义view相关学习
学习材料: http://blog.csdn.net/u010661782/article/details/52805870 http://blog.csdn.net/chengyingzhilian ...
- python 读取hive数据
话不多说,直接上代码 from pyhive import hivedef pyhive(hql): conn = hive.Connection(host='HiveServer2 host', p ...
- Docker实践(二):容器的管理(创建、查看、启动、终止、删除)
docker官方文档地址如下:[https://docs.docker.com/engine/reference/](https://docs.docker.com/engine/reference/ ...
- C# 加特效
public class BulletMove : MonoBehaviour { public float Speed = 5f; public Transform Fx; // Use this ...
- XML hexadecimal value 0x__, is an invalid character
XML操作时异常:(十六进制值 0x__) 是无效的字符. 方法一: 设置 CheckCharacters=false. XmlReaderSettings xmlReaderSettings = n ...