vue:封装垂直方向滚动渐变遮罩层组件

需求描述

系统中经常会有需要垂直滚动的页面,滚动容器的上下边一般都是“实”的,会将滚动内容清晰截断;如果在容器上下增加一段和背景同色的渐变遮罩层,那么滚动内容将产生一种“渐入渐出”的效果,对比如下:
vue:封装垂直方向滚动渐变遮罩层组件_第1张图片

实现要点

1、渐变遮罩层的z-index高于容器内容,需要给遮罩层加上pointer-events: none;让鼠标“穿透”到下层;
2、当内容滚动到顶部或底部时,需隐藏顶部或底部的遮罩层,防止遮挡显示内容;
3、外层容器带有圆角时,内层内容需要设置同样的圆角,否则滚动时圆角效果会出bug。

参考代码

此处附上本杂鱼封装的渐变遮罩层组件GradientCover代码,仅供参考:

<!-- 在可垂直滚动的div上下增加渐变色遮罩层,且滚动到顶部或底部时隐藏遮罩层 -->
<template>
  <div id="GradientCover">
    <div v-show="showGradientCover[0]" class="gradientMask top" 
      :style="`height: ${coverHeight}px;margin-bottom: -${coverHeight}px;`"
    ></div>
    <div class="container" @scroll="scrollContent" ref="scrollContent"
      :style="`overflow: ${overflow};border-radius: 0 0 ${borderRadius}px ${borderRadius}px;`"
    >
      <slot></slot>
    </div>
    <div v-show="showGradientCover[1]" class="gradientMask bottom" 
      :style="`height: ${coverHeight}px;margin-top: -${coverHeight}px;border-radius: 0 0 ${borderRadius}px ${borderRadius}px;`"
    ></div>
  </div>
</template>

<script>
	export default {
		props: {
			overflow: { // 是否可滚动
				type: String,
				default: () => 'hidden'
			},
			coverHeight: { // 遮罩高度
				type: [String, Number],
				default: () => 32
			},
			borderRadius: { // 外层容器圆角
				type: [String, Number],
				default: () => 0
			}
		},
		data () {
			return {
				// 是否显示渐变遮罩层(初始处于顶部,不显示顶部遮罩,显示底部遮罩)
				showGradientCover: [ false, this.overflow !== 'hidden' ]
			}
		},
		watch: {
			overflow: {
				immediate: true,
				handler (newVal) { // 页面滚动样式变化时,更新遮罩层可见配置
					this.showGradientCover = [ false, newVal !== 'hidden' ]
				}
			}
		},
		methods: {
			scrollContent (e) {
				this.showGradientCover = [
					// 滚动到距离顶部<20px时,隐藏顶部渐变遮罩层;否则显示
					20 < e.srcElement.scrollTop, 
					// 滚动到距离底部<20px时,隐藏底部渐变遮罩层;否则显示
					e.srcElement.scrollTop + e.srcElement.offsetHeight + 20 
						< e.srcElement.scrollHeight
				]
			},
			scrollTop () { // 滚动到顶部
				this.$refs.scrollContent.scrollTop= 0
			}
		}
	}

</script>

<style lang="less" scoped>
	#GradientCover {
		height: 100%;
		width: 100%;

		.gradientMask {
			pointer-events: none;
			z-index: 100;
			position: relative;
			left: 0;
			width: calc(100% - 8px); // 8px是滚动条的宽度

			&.top {
				top: 0;
				background: linear-gradient(180deg, #ffffff, transparent);
			}
			&.bottom {
				bottom: 0;
				background: linear-gradient(0deg, #ffffff, transparent);
			}
		}

		.container {
			width: 100%;
			height: 100%;
		}
	}
</style>

你可能感兴趣的:(vue.js,javascript,前端)