vue 组件封装 | s-fullpage 全屏滚动 (内含绑定鼠标滑轮滚动事件、避免鼠标滑轮连续滚动、滑动过渡动画等实用技巧)
目录
目标
实现原理(要点)
完整代码 s-fullpage 和 s-fullpageItem
s-fullpage.vue
s-fullpageItem.vue
使用范例
范例效果
目标
实现类似插件 vue-fullpage.js 的全屏滚动翻页效果( vue-fullpage.js 的教程详见 https://blog.csdn.net/weixin_41192489/article/details/111104443)
实现原理(要点)
1. 使用 “子绝父相” 定位,实现上下滑动过渡动画翻页(滑动动画的实现原理,详见 https://blog.csdn.net/weixin_41192489/article/details/112271981 )
2. 通过插槽获取页面列表,根据下标变化完成翻页
this.$slots.default.forEach(item => {this.pageList.push(item.componentOptions.propsData.page)
})
this.currentPage = this.pageList[this.currentIndex]
3. 绑定鼠标滑轮滚动事件,通过限定事件触发时间间隔,来避免连续滚动触发越级翻页
@wheel.prevent="mouseWheel"
// 鼠标滑轮滚动事件
mouseWheel(e) {this.startTime = new Date().getTime()// 每次滚动事件触发1s后,才会再次触发(避免鼠标滚动事件连续触发)if (this.startTime - this.endTime > 1000) {…… // 执行翻页事件,翻页完成后,执行 this.endTime = new Date().getTime()}
}
4. 通过监听下标变化来切换向上翻页和向下翻页的过渡动画
watch: {'$parent.currentIndex'(newIndex, oldindex) {if (newIndex >= oldindex) {// 向下翻页时,使用向下翻页的动画,默认为从下方滑入,从上方滑出this.inClass = this.nextInClassthis.outClass = this.nextOutClass} else {// 向上翻页时,使用向上翻页的动画,默认为从上方滑入,从下方滑出this.inClass = this.previousInClassthis.outClass = this.previousOutClass}}
},
完整代码 s-fullpage 和 s-fullpageItem
全屏滚动通过封装 父组件 s-fullpage 和 子组件 s-fullpageItem 来配合实现
s-fullpage.vue
<template><div @wheel.prevent="mouseWheel" class="fullpage"><!--指示器--><div class="fixed__indicatorsBox" :style="indicatorsBoxStyle"><div @click="goto(index)" :class="{'active_indicator':currentIndex === index}" class="indicator"v-for="(item,index) in pageList" :key="index"></div></div><slot></slot></div>
</template>
<script>export default {name: "s-fullpage",props: {// 默认显示页activePage: String,// 指示器的位置indicatorPosition: {type: String,default: 'right'}},mounted() {if (this.indicatorPosition === 'right') {this.$set(this.indicatorsBoxStyle, 'right', 0)} else if (this.indicatorPosition === 'left') {this.$set(this.indicatorsBoxStyle, 'left', 0)}this.$slots.default.forEach(item => {this.pageList.push(item.componentOptions.propsData.page)})if (!this.activePage && this.pageList.length > 0) {this.currentPage = this.pageList[0]} else {this.currentPage = this.activePagethis.pageList.forEach((item, index) => {if (this.currentPage === item) {this.currentIndex = index}})}},data() {return {indicatorsBoxStyle: {},// 所有页构成的列表pageList: [],// 当前显示页currentPage: '',// 当前显示页的下标currentIndex: 0,// 鼠标滑轮滚动的方向direction: '',// 鼠标滑轮事件开始时间startTime: '',// 鼠标滑轮指令执行结束时间endTime: '',}},methods: {// 页面跳转goto(index) {this.currentIndex = indexthis.currentPage = this.pageList[index]},// 鼠标滑轮滚动事件mouseWheel(e) {this.startTime = new Date().getTime()// 每次滚动事件触发1s后,才会再次触发(避免鼠标滚动事件连续触发)if (this.startTime - this.endTime > 1000) {e = e || window.event;if (e.wheelDelta) { //IE,谷歌浏览器滑轮事件if (e.wheelDelta > 0) {// 向上滚动this.previousPage()}if (e.wheelDelta < 0) {// 向下滚动this.nextPage()}} else if (e.detail) { //Firefox滑轮事件if (e.detail > 0) {// 向上滚动this.previousPage()}if (e.detail < 0) {// 向下滚动this.nextPage()}}}},previousPage() {this.direction = 'up'this.currentIndex -= 1// 第1页时,禁止继续向上翻页if (this.currentIndex < 0) {this.currentIndex = 0}this.currentPage = this.pageList[this.currentIndex]this.endTime = new Date().getTime()},nextPage() {this.direction = 'down'this.currentIndex += 1// 最后一页时,禁止继续向下翻页if (this.currentIndex > this.pageList.length - 1) {this.currentIndex = this.pageList.length - 1}this.currentPage = this.pageList[this.currentIndex]this.endTime = new Date().getTime()},}}
</script>
<style scoped>/*指示器容器的样式*/.fixed__indicatorsBox {position: fixed;top: 50%;transform: translateY(-50%);z-index: 999;}/*指示器的样式*/.indicator {height: 16px;width: 16px;border-radius: 50%;background: white;opacity: 0.3;margin: 10px;cursor: pointer;}/*当前指示器的样式*/.active_indicator {opacity: 1;box-shadow: 0px 0px 8px 2px white;}.fullpage {height: 100vh;width: 100vw;color: white;background: black;position: relative;/*隐藏滚动条*/overflow: hidden;}/*滑出——从上方*/.slidOutFromTop {animation: slidOutFromTop 1s;}@keyframes slidOutFromTop {from {top: 0;}to {top: -100%;}}/*滑出——从下方*/.slidOutFromBottom {animation: slidOutFromBottom 1s;}@keyframes slidOutFromBottom {from {top: 0;}to {top: 100%;}}/*滑入——从上方*/.slidInFromTop {animation: slidInFromTop 1s;}@keyframes slidInFromTop {from {top: -100%;}to {top: 0;}}/*滑入——从下方*/.slidInFromBottom {animation: slidInFromBottom 1s;}@keyframes slidInFromBottom {from {top: 100%;}to {top: 0;}}
</style>
s-fullpageItem.vue
<template><transition:enter-active-class="inClass":leave-active-class="outClass"><div v-show="$parent.currentPage === page" class="s_fullpageItem"><slot></slot></div></transition>
</template>
<script>export default {name: "s-fullpageItem",props: {// 页面标识,必传且不能与其他页重复!page: {type: String,required: true},nextInClass: {type: String,default: 'slidInFromBottom'},nextOutClass: {type: String,default: 'slidOutFromTop'},previousInClass: {type: String,default: 'slidInFromTop'},previousOutClass: {type: String,default: 'slidOutFromBottom'},},watch: {'$parent.currentIndex'(newIndex, oldindex) {if (newIndex >= oldindex) {// 向下翻页时,使用向下翻页的动画,默认为从下方滑入,从上方滑出this.inClass = this.nextInClassthis.outClass = this.nextOutClass} else {// 向上翻页时,使用向上翻页的动画,默认为从上方滑入,从下方滑出this.inClass = this.previousInClassthis.outClass = this.previousOutClass}}},data() {return {inClass: '',outClass: '',}},}
</script>
<style scoped>.s_fullpageItem {position: absolute;height: 100vh;width: 100vw;text-align: center;display: flex;justify-content: center;align-items: center;}/*滑出——从上方*/.slidOutFromTop {animation: slidOutFromTop 1s}@keyframes slidOutFromTop {from {top: 0;}to {top: -100%;}}/*滑出——从下方*/.slidOutFromBottom {animation: slidOutFromBottom 1s}@keyframes slidOutFromBottom {from {top: 0;}to {top: 100%;}}/*滑入——从上方*/.slidInFromTop {animation: slidInFromTop 1s}@keyframes slidInFromTop {from {top: -100%;}to {top: 0;}}/*滑入——从下方*/.slidInFromBottom {animation: slidInFromBottom 1s}@keyframes slidInFromBottom {from {top: 100%;}to {top: 0;}}
</style>
使用范例
<template><div><s-fullpage activePage="2" indicatorPosition="left"><s-fullpageItem page="1" >第1页</s-fullpageItem><s-fullpageItem page="2" style="background: blue">第2页</s-fullpageItem><s-fullpageItem page="3" style="background: green">第3页</s-fullpageItem></s-fullpage></div>
</template>
范例效果
vue 组件封装 | s-fullpage 全屏滚动 (内含绑定鼠标滑轮滚动事件、避免鼠标滑轮连续滚动、滑动过渡动画等实用技巧)相关推荐
- Vue 组件封装之 ScrollView 上拉加载更多
Vue 组件封装之 ScrollView 上拉加载更多 一.ScrollView 上拉加载更多 二.使用案例 三.API 使用指南 四.源代码 一.ScrollView 上拉加载更多 组件说明: 实现 ...
- Vue 组件封装之 Questionnaire 问卷调查
Vue 组件封装之 Questionnaire 问卷调查 前言 一.Questionnaire 组件 二.使用案例 三.API 使用指南 四.源代码 前言 问卷调查表也是目前前端比较常见的开发项目,目 ...
- Vue 组件封装之 Content 列表(处理多行输入框 textarea)
Vue 组件封装之 Content 列表 一.Content 列表 二.使用案例 三.API 使用指南 四.源代码 一.Content 列表 组件说明: 实现 Content 列表布局排版. 效果展示 ...
- Vue 组件封装之 List 列表
Vue 组件封装之 List 列表 一.List 列表 二.使用案例 三.API 使用指南 四.源代码 一.List 列表 组件说明: 实现 List 列表布局排版. 效果展示: 实现的功能: 在一个 ...
- Vue 组件封装之 Search 搜索
Vue 组件封装之 Search 搜索 一.Search 组件 二.使用案例 三.API 使用指南 四.源代码 一.Search 组件 组件说明: 实现搜索功能. 效果展示: input 输入框背景铺 ...
- Vue组件封装,(面试回答)
在我用vue开发项目的时候,一般我都会用到组件封装,采用组件化的思想进行项目开发,我在搭建一个项目的时候,就会创建一个views目录和一个commen目录和一个feature目录,views目录中放页 ...
- Vue 组件封装之 Tab 切换
Vue 组件封装之 tab 切换 一.Tab 切换组件 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tab 切换组件 组件说明: 实现 tab 切换. 效果展示: 实现 tab 切换 ...
- Vue组件封装的过程
Vue组件封装的过程 vue组件的定义 组件(Component)是Vue.js最强大的功能之一 组件可以扩展HTML元素,封装可重用代码 在较高层面上,组件是自定义元素,Vue.js的编译器为他添加 ...
- Vue 组件封装、组件传值、数据修改
Vue 组件封装 封装的意义 当一个页面元素过多或者一个组件在多个页面都会被使用,就可以进行组件封装,可以对单个页面解耦,增加代码的可读性,并且多次使用的组件方便修改,只用修改一个地方就能对用到这个组 ...
最新文章
- C# 中字符串string和字节数组byte[]的转换,16 进制字符串转 int的方法
- 7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)
- Linux下多网卡MAC配置问题
- 前端一HTML:一: 浏览器,服务器,请求报文
- 雨棚板弹性法计算简图_钢结构工程量计算、报价要点
- 成年人改变生活的方式,都是从它开始
- 小程序引入的echarts过大如何解决_微信小程序中使用echarts
- jquerymobile iscrollview
- vs2005/vs2008 快捷键【转】
- tensorflow学习3---mnist
- 服务器复制不进去文件等
- OSChina 周二乱弹 ——流川枫与苍井空
- 编程之路之数据库(十)- PDO详解
- 微信企业号上传图片 php,C#开发微信门户及应用微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)...
- 【dev Cpp新手请进】dev导入ege图形库
- 卓训教育:如何批评孩子,正确批评孩子的方法
- “七夕情歌会 缘聚红豆峡” 红豆峡第15届情歌会圆满结束
- sct分散加载文件格式与应用
- (CVE-2014-0160)OpenSSL 心脏出血漏洞
- python熊猫弹幕_GitHub - qingyuj/danmu: Python 弹幕包 A live danmu package for python
热门文章
- bzoj2066: [Poi2004]Gra
- LVGL 8.2.0之Faded area line chart with custom division lines
- SOLIDWORKS仿真等幅载荷高周疲劳的分析应用
- python微信聊天机器人,自动翻译
- DOVE-----Vue.js框架入门(九)
- 微信公众号css实现滑动效果,基于HTML/CSS/JS微信公众号展示页面模板
- Web练习题---简历表页面的制作
- VR内容或成VR产业真正盈利点
- php抽奖算法,php抽奖算法
- 配置NTOP局域网流量监控