目录环境准备:实现步骤:数据结构基本html使用better-scroll实现内容区列表的滚动给索引添加点击事件和移动事件实现跳转给索引添加高亮全部代码总结参考文献如?图,实现一个滚
如?图,实现一个滚动内容区域,右侧字母滚动索引定位;选择和拖动字母索引,对应内容滚动到视窗
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综合征']
}
]
};
}
};
<!-- 内容区域 -->
<!-- 最外层父容器wrapper,固定高度并且overflow:hidden-->
<div class="h-534px flex-1 wrapper overflow-hidden" ref="wrapper">
<!-- content 注意滚动区域一定是父容器的第一个子元素,当高度超出父容器即可滚动 -->
<ul class="content">
<!-- v-for 循环出列表 -->
<li
v-for="(item, index) in entityList"
:key="index"
class="flex flex-col"
ref="listGroup"
>
<div
class="h-42px leading-42px text-sm font-bold pl-15px w-244px"
>
{{ item.key }}
</div>
<div class="flex flex-col">
<span
class="h-42px leading-42px text-sm pl-15px g-clamp1 w-244px"
v-for="(it, i) in item.list"
:key="i"
>
{{ it }}
</span>
</div>
</li>
</ul>
</div>
<!-- 索引 -->
<ul class="entityList w-15px bg-white">
<!-- v-for 循环出索引 -->
<li
v-for="(item, index) in entityList"
:key="index"
:data-index="index"
class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
>
{{ item.key }}
</li>
</ul>
<script>
//import 引入BScroll
import BScroll from '@better-scroll/core';
import MouseWheel from '@better-scroll/mouse-wheel';
BScroll.use(MouseWheel);
export default {
mounted() {
//dom渲染完毕,初始化better-scroll
this.$nextTick(() => {
this.initBanner();
});
},
methods: {
initBanner() {
if (this.scroll && this.scroll.destroy){
this.scroll.refresh();//当 DOM 结构发生变化的时候需重新计算 BetterScroll
this.scroll.destroy();//销毁 BetterScroll,解绑事件
}
this.scroll = new BScroll('.wrapper', {
scrollY: true,//纵向滚动
click: true,
mouseWheel: true,
disableMouse: false, //启用鼠标拖动
disableTouch: false, //启用手指触摸
probeType: 3 //设置为3,BetterScroll实时派发 scroll 事件
});
}
}
};
</script>
?注意:这里我们在mounted时期,在this.$nextTick 的回调函数中初始化 better-scroll 。这时wrapper 的 DOM 已经渲染了,我们可以正确计算它以及它内层 content 的高度,以确保滚动正常。
<ul class="entityList w-15px bg-white">
<li
v-for="(item, index) in entityList"
:key="index"
:data-index="index"
class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
@touchstart="onShortcutStart" //点击事件
@touchmove.stop.prevent="onShortcutMove" //移动事件
>
{{ item.key }}
</li>
</ul>
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() {
return {
currentIndex: 0,
entityList: [
{
key: 'A',
list: ['氨基酸代谢病', '广泛性发育障碍']
}]
}
}
<ul class="entityList w-15px bg-white">
<li
v-for="(item, index) in entityList"
:key="index"
:data-index="index"
class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
@touchstart="onShortcutStart"
@touchmove.stop.prevent="onShortcutMove"
:class="{ current: currentIndex === index }"
>
{{ item.key }}
</li>
</ul>
接下来求currentIndex:
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() {
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() {
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 实现索引高亮的特效
<template>
<div>
<!-- 内容区域 -->
<div class="h-534px flex-1 wrapper overflow-hidden" ref="listview">
<ul class="content">
<li
v-for="(item, index) in entityList"
:key="index"
class="flex flex-col"
ref="listGroup"
>
<div class="h-42px leading-42px text-sm font-bold pl-15px w-244px">
{{ item.key }}
</div>
<div class="flex flex-col">
<Link
class="h-42px leading-42px text-sm pl-15px g-clamp1 w-244px"
v-for="(it, i) in item.list"
:key="i"
:to="{
name: 'Yidian',
query: {
title: it
}
}"
>
{{ it }}
</Link>
</div>
</li>
</ul>
</div>
<!-- 索引 -->
<ul class="entityList w-15px bg-white">
<li
v-for="(item, index) in entityList"
:key="index"
:data-index="index"
class="w-3 text-4 h-3 mb-1 leading-3 text-center text-gray6"
@touchstart="onShortcutStart"
@touchmove.stop.prevent="onShortcutMove"
:class="{ current: currentIndex === index }"
>
{{ item.key }}
</li>
</ul>
</div>
</template>
<script>
import BScroll from '@better-scroll/core';
import MouseWheel from '@better-scroll/mouse-wheel';
BScroll.use(MouseWheel);
export default {
data() {
return {
currentIndex: 0,
listHeight: [],
entityList: [
{
key: 'A',
list: ['氨基酸代谢病', '广泛性发育障碍']
},
{
key: 'B',
list: ['巴特综合征', '包涵体性结膜炎', '膀胱外翻', '鼻腔结外型NK/T细胞淋巴瘤']
},
{
key: 'C',
list: ['C5功能不全综合征', '肠道蛔虫症', '喘息样支气管炎']
},
{
key: 'D',
list: ['低氯性氮质血症综合征', '石棉状糠疹', 'Dravet综合征']
},
{
key: 'E',
list: ['耳聋', '儿童癫痫', '儿童头痛', '儿童急性中耳炎']
},
{
key: 'F',
list: ['腹肌缺如综合征', '肥大性神经病', '肺缺如', '樊尚咽峡炎', '腹壁疝']
}
],
scrollY: -1
};
},
mounted() {
this.touch = {};
this.$nextTick(() => {
this.initBanner();
});
},
methods: {
//初始化scroll
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
});
this._calculateHeight();
this.scroll.on('scroll', pos => {
console.log(pos.y);
this.scrollY = pos.y;
});
},
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;
//注意这里需要判断边界,不然拖动到顶部和底部会报错
if (index >= 0 && index <= this.entityList.length - 2) {
this.scroll.scrollToElement(this.$refs.listGroup[index]);
}
},
//计算索引内容高度
_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);
}
}
},
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;
}
}
};
</script>
<style scoped lang="postCSS">
.tabActive {
@apply font-bold;
}
.tabActive::after {
content: '';
display: block;
width: 18px;
height: 3px;
background: #00c2b0;
border-radius: 2px;
position: absolute;
bottom: 0;
}
.sortActive {
color: #00c2b0;
}
.select-left {
@apply w-110px;
}
.select-left-item {
@apply pl-15px h-42px text-sm;
}
.entityList {
position: fixed;
right: 8px;
top: 156px;
}
.current {
border-radius: 50%;
background: #00beb0;
color: #fff;
}
.typeAct {
@apply bg-white text-primary;
}
</style>
better-scroll官方文档
参考博客
到此这篇关于Vue+better-scroll 实现通讯录字母索引的文章就介绍到这了,更多相关Vue+better-scroll 实现通讯录字母索引内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Vue+better-scroll实现通讯录字母索引的示例代码
本文链接: https://lsjlt.com/news/150857.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0