这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
滚到外婆桥
左右摇摆
如果说之前的轮播图还能因为其常见性,普遍性而跻身布局组件的话, 那么滚动这个也能算布局组件?
无论是从普遍性,还是其本身功能的局限性,将之作为业务组件才更符合常理的吧?
NO!NO!NO! 作为一名开发者,自然是要有着远超旁人的创新性,以及看待事物的独特角度。
接下来就看我先瞎编一段。
将之作为布局组件而非业务组件的主要原因在于,该组件本质上也是提供一个常见的“平台”,内容由开发者去定义。
而功能部分也是做的滚动到底部触发时间。将内容交给开发者之后,组件本身的部分就更符合一个布局组件所具备的素质了。
听懂掌声!
说到底,我对布局组件的理解就是:提供平台,内容交给开发时。
而业务组件更多的是根据需求对其他组件进行二次封装,或者专门去开发一个组件。
开始搞事
既然是只搭平台, 那就做好一个平台要做的事吧, 从结构开始就要做好一个平台的分内事了。
block content
div.yx-scroll(
:style="{height: `${viewHeight}px`}"
@mouseenter="mouseover"
@mouseleave="mouseout"
)
div.yx-scroll-content(
:style="{paddingRight: `${size}px`}"
@scroll="viewScroll"
)
slot
transition(name="fade")
div.yx-scroll-bar(
v-show="!alwaysVisible || isShow"
:style="{width: `${size}px`}"
@mousedown="thumbDrag($event)"
)
div.yx-scroll-thumb(
ref="thumb"
:style="{height: `${barHeight}px`,top: `${barTop}px`,borderRadius: `${size}px` }"
)
结构部分比较清晰,主要是监听滚动事件,回顶、滚动到底部的交给逻辑部分去判断,
此外在该组件中的滚动条是自定义的,而非系统默认的,不过这个就随意了,可以自由发挥。
逻辑部分
还是老规矩,挑重点说。
先看滚动条。
const thumbDrag = (e) => {
e.preventDefault()
// 分别获取节点、滚动值等信息
const el = ctx.vnode.el
const view = el.children[0]
const touchY = e.clientY - BarTop.value
const element = e.target
// 计算滚动高度,以及显示滚动条的高度
if (element.className === 'yx-scroll-bar') {
const top = e.clientY - element.getBoundingClientRect().top
view.scrollTop =
view.scrollHeight * (top / element.offsetHeight) -
element.offsetHeight / 2
} else {
const move = (ev) => {
isDrag = true
const bt =
(ev.clientY - touchY) /
(view.offsetHeight - thumb.value.offsetHeight)
const top = (view.scrollHeight - view.offsetHeight) * bt
view.scrollTop = top
}
document.addEventListener('mousemove', move)
document.addEventListener('mouseup', () => {
isDrag = false
if (!isArea) {
isShow.value = false
}
document.removeEventListener('mousemove', move)
})
}
}
事件监听
const emits = defineEmit(['onScroll','update:to']);
const viewScroll = () => {
const el = ctx.vnode.el;
const view = el.children[0];
const catchTop = view.scrollTop / (view.scrollHeight - view.offsetHeight);
barTop.vuew = catchTop * (view.offsetHeight - thumb.value.offsetHeight);
emits('onScroll', catchTop);
emits('update:to', view.scrollTop);
}
这里的catchTop计算的是当前滚动距离的百分比, 取值: 0 ~ 1, 传值给父级是方便父级如果需要的话,可以自行判断当前百分比,并完善自动加载的函数。
其他
其他的部分都是属于比较灵活的点的了,可以根据自己对组件的预期,或者是项目中的需求来改动组件,使其更贴合自己项目中的使用。