本来想一篇文章写完,但是又截图又分析什么的,如果用一篇文章写,太长了,估计都没耐心看完,所以分成了几篇来写。
这篇主要说的是实现点击右侧字母索引,左边能自动滚动到相应城市功能。
兄弟组件联动
去字母索引组件的循环的li
部分添加一个点击事件,这个点击事件接收一个e
的事件对象,拿到事件对象,可以先打印e.target.innerText
,这个时候去浏览器看看。
此时点击字母索引中的任意一个字母,控制台会打印出相应字母的文字。
此时我们希望将字母传给
list
组件,(list
组件就是城市列表组件)然后让list
对应的区块显示出来。list
组件和字母索引组件是兄弟组件,这里就涉及到兄弟组件的传值,它们是非父子组件,可通过bus总线的形式来传值。由于这里传递的数据比较简单,就是ABCD...,并且组件的层级不深,所以我们可以将字母索引组件的值传递给
City
这个父组件,然后父组件再传给list
,这里的兄弟组件传值就变成了子组件传给父组件,父组件再传给另一个子组件的形式了。
字母索引组件传值给City父组件
给li
定义一个点击事件,当点击字母的时候,向父组件派发一个change
事件,这个事件带的内容就是e.target.innerText
,
然后去
City
父组件接收这个事件,用名为handleLetterChange
的函数来接收@change
事件。接收一下事件
接收函数打印一下带来的参数内容letter
打印一下带来的参数内容
当我们点击字母的时候,字母在控制台被打印出来,由
City
组件打印出来的,也就表明了 父组件成功接收了子组件传过来的消息。成功打印
City父组件再将内容转发给list组件
父组件通过绑定属性的形式传给子组件数据,先在父组件的data
部分定义一个letter
的变量,为空,也就是letter: ''
,
然后再去handleLetterChange
函数中让this.letter = letter
,也就是让传过来的参数赋值给本地的letter
,再给list
组件绑定一个letter
属性,将本地的letter
传递过去。
然后list
子组件去接收这个letter
。
接收后的逻辑
接收到letter
要怎样呢?
当list
的组件发现letter
有改变的时候,让组件显示的列表项和letter
相同的首字母列表项显示出来。
在这里要借助一个侦听器watch
,监听letter
,一旦它变化了,就要做点事了。
比如说当letter
变的时候,将它打印出来:
一旦
letter
发生改变,就会执行这段代码:成功监听到
在watch
这个侦听器具体做什么呢?
如果letter
不为空的时候,调用betterScroll
的一个方法,让better-scroll
自动滚动到某个元素上,外部传一个A,就滚动到A区域上。
怎么做呢?
首先,去循环处拿到dom
节点,还记得上篇说的两层循环吗?这里要拿的就是父级循环的ABCD的值,通过:ref="key"
,记住这里是:ref
而不是ref
,意思是要绑定key
的值。
然后去watch
侦听器获取这层dom
结构,定义element来接收它。
this.$refs[this.letter]
的的意思是,原本我们要获取某层dom
是这样写的:
模板处:ref="xxx"
script部分: this.$refs.xxx
但是这里模板处是绑定的值
模板处: :ref="xxx"
script部分: this.$refs.xxx 这里原本应该是这样写的,
在js中xx.xxx 和xx[xxx]是一个意思,
所以也可以改写为this.$refs[xxx],xxx应该为传入的letter值,因为这里的xxx是绑定的值
就像这样
好啦,理想很丰满,现实很骨感。本来理论上应该就是这么写就可以了,但是当我们打印出来
element
的值,它居然不是一个dom
对象!!而是一个数组:
变成了数组了
为啥?因为我们的
ref
是一个循环输出的ref
,使用循环输出的ref
的时候,它其实是一个数组。真正的dom
元素在我标框框的地方。或取它也就是获取下标0的内容就行了效果粗剪版
拿到之后,将这个
dom
元素传给scrollToElement
里。
到这里,点击A,A部分内容就出来了,粗剪版的效果就完成了。
下一篇说,滑动右侧字母索引,左侧对应滑动,做一个字母索引的滚动监听。
网友评论