如图,实现一个滚动内容区域,右侧字母滚动索引定位;选择和拖动字母索引,对应内容滚动到视窗
环境准备:
- 安装better-scroll npm包
- 安装 mouseWheel 扩展 BetterScroll 鼠标滚轮的能力,开启鼠标滚动(移动端非必须)
npm install @better-scroll/core @better-scroll/mouse-wheel --save
实现步骤:
数据结构
- 内容区和索引按下图数据结构处理
export default { data() { return { entityList: [ { key: 'A', list: ['氨基酸代谢病', '广泛性发育障碍'] }, { key: 'B', list: ['巴特综合征', '包涵体性结膜炎', '膀胱外翻', '鼻腔结外型NK/T细胞淋巴瘤'] }, { key: 'C', list: ['C5功能不全综合征', '肠道蛔虫症', '喘息样支气管炎'] }, { key: 'D', list: ['低氯性氮质血症综合征', '石棉状糠疹', 'Dravet综合征'] } ] }; } };
基本HTML
{{ item.key }}{{ it }}
- {{ item.key }}
使用better-scroll实现内容区列表的滚动
注意:这里我们在mounted时期,在this.$nextTick 的回调函数中初始化 better-scroll 。这时wrapper 的 DOM 已经渲染了,我们可以正确计算它以及它内层 content 的高度,以确保滚动正常。
给索引添加点击事件和移动事件实现跳转
- {{ item.key }}
created() { // 添加一个 touch 用于记录移动的属性 this.touch = {}; this.$nextTick(() => { this.initBanner(); }); }, methods: { onShortcutStart(e) { // 获取到绑定的 index let index = e.target.getAttribute('data-index'); // 使用 better-scroll 的 scrollToElement 方法实现跳转 this.scroll.scrollToElement(this.$refs.listGroup[index]); // 记录一下点击时候的 Y坐标 和 index let firstTouch = e.touches[0].pageY; this.touch.y1 = firstTouch; this.touch.anchorIndex = index; }, onShortcutMove(e) { // 再记录一下移动时候的 Y坐标,然后计算出移动了几个索引 let touchMove = e.touches[0].pageY; this.touch.y2 = touchMove; // 这里的 16.7 是索引元素的高度 let delta = Math.floor((this.touch.y2 - this.touch.y1) / 18); // 计算最后的位置 let index = this.touch.anchorIndex * 1 + delta; this.scroll.scrollToElement(this.$refs.listGroup[index]); } }
给索引添加高亮
- 在data中定义currentIndex用于索引高亮的判断,并在html中绑定class
data() { return { currentIndex: 0, entityList: [ { key: 'A', list: ['氨基酸代谢病', '广泛性发育障碍'] }] } }
- {{ item.key }}
接下来求currentIndex:
- 先通过better-scroll 的on(type, fn, context)方法,监听当前实例上的scroll,得到内容区y轴的偏移量
initBanner() { if (this.scroll && this.scroll.destroy) { this.scroll.refresh(); this.scroll.destroy(); } this.scroll = new BScroll('.wrapper', { scrollY: true, click: true, mouseWheel: true, disableMouse: false, //启用鼠标拖动 disableTouch: false, //启用手指触摸 probeType: 3 }); // 监听Y轴偏移的值 this.scroll.on('scroll', pos => { this.scrollY = pos.y; }); },
- data中初始化 listHeight ,添加calculateHeight() 方法计算内容区高度
data() { return { listHeight: [], currentIndex: 0, entityList: [ { key: 'A', list: ['氨基酸代谢病', '广泛性发育障碍'] } ] } }
//计算内容区高度 _calculateHeight() { this.listHeight = []; const list = this.$refs.listGroup; let height = 0; this.listHeight.push(height); for (let i = 0; i < list.length; i++) { let item = list[i]; //累加之前的高度 height += item.clientHeight; this.listHeight.push(height); } }
- data中初始化scrollY为-1,在 watch 中监听 scrollY
data() { return { scrollY: -1 currentIndex: 0, listHeight: [], entityList: [ { key: 'A', list: ['氨基酸代谢病', '广泛性发育障碍'] } ] } }
watch: { scrollY(newVal) { // 向下滑动的时候 newVal 是一个负数,所以当 newVal > 0 时,currentIndex 直接为 0 if (newVal > 0) { this.currentIndex = 0; return; } // 计算内容区高度判断 对应索引currentIndex 的值 for (let i = 0; i < this.listHeight.length - 1; i++) { let height1 = this.listHeight[i]; let height2 = this.listHeight[i + 1]; if (-newVal >= height1 && -newVal < height2) { this.currentIndex = i; return; } } // 当超 -newVal > 最后一个高度的时候 // 因为 this.listHeight 有头尾,所以需要 - 2 this.currentIndex = this.listHeight.length - 2; } }
这样就得到了currentIndex 实现索引高亮的特效
全部代码
{{ item.key }}{{ it }}
- {{ item.key }}
总结
- 参考了很多网上的资料,相对于原生实现,better-scroll带来了更大的便利,但是同时也需要我们对better-scroll有一定的了解。
参考文献
better-scroll官方文档
参考博客
到此这篇关于Vue+better-scroll 实现通讯录字母索引的文章就介绍到这了,更多相关Vue+better-scroll 实现通讯录字母索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!