目录

目标

实现原理(要点)

完整代码 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 全屏滚动 (内含绑定鼠标滑轮滚动事件、避免鼠标滑轮连续滚动、滑动过渡动画等实用技巧)相关推荐

  1. Vue 组件封装之 ScrollView 上拉加载更多

    Vue 组件封装之 ScrollView 上拉加载更多 一.ScrollView 上拉加载更多 二.使用案例 三.API 使用指南 四.源代码 一.ScrollView 上拉加载更多 组件说明: 实现 ...

  2. Vue 组件封装之 Questionnaire 问卷调查

    Vue 组件封装之 Questionnaire 问卷调查 前言 一.Questionnaire 组件 二.使用案例 三.API 使用指南 四.源代码 前言 问卷调查表也是目前前端比较常见的开发项目,目 ...

  3. Vue 组件封装之 Content 列表(处理多行输入框 textarea)

    Vue 组件封装之 Content 列表 一.Content 列表 二.使用案例 三.API 使用指南 四.源代码 一.Content 列表 组件说明: 实现 Content 列表布局排版. 效果展示 ...

  4. Vue 组件封装之 List 列表

    Vue 组件封装之 List 列表 一.List 列表 二.使用案例 三.API 使用指南 四.源代码 一.List 列表 组件说明: 实现 List 列表布局排版. 效果展示: 实现的功能: 在一个 ...

  5. Vue 组件封装之 Search 搜索

    Vue 组件封装之 Search 搜索 一.Search 组件 二.使用案例 三.API 使用指南 四.源代码 一.Search 组件 组件说明: 实现搜索功能. 效果展示: input 输入框背景铺 ...

  6. Vue组件封装,(面试回答)

    在我用vue开发项目的时候,一般我都会用到组件封装,采用组件化的思想进行项目开发,我在搭建一个项目的时候,就会创建一个views目录和一个commen目录和一个feature目录,views目录中放页 ...

  7. Vue 组件封装之 Tab 切换

    Vue 组件封装之 tab 切换 一.Tab 切换组件 二.使用案例 三.API 使用指南 四.源代码 五.总结 一.Tab 切换组件 组件说明: 实现 tab 切换. 效果展示: 实现 tab 切换 ...

  8. Vue组件封装的过程

    Vue组件封装的过程 vue组件的定义 组件(Component)是Vue.js最强大的功能之一 组件可以扩展HTML元素,封装可重用代码 在较高层面上,组件是自定义元素,Vue.js的编译器为他添加 ...

  9. Vue 组件封装、组件传值、数据修改

    Vue 组件封装 封装的意义 当一个页面元素过多或者一个组件在多个页面都会被使用,就可以进行组件封装,可以对单个页面解耦,增加代码的可读性,并且多次使用的组件方便修改,只用修改一个地方就能对用到这个组 ...

最新文章

  1. C# 中字符串string和字节数组byte[]的转换,16 进制字符串转 int的方法
  2. 7-5 顺序存储的二叉树的最近的公共祖先问题(25 分)
  3. Linux下多网卡MAC配置问题
  4. 前端一HTML:一: 浏览器,服务器,请求报文
  5. 雨棚板弹性法计算简图_钢结构工程量计算、报价要点
  6. 成年人改变生活的方式,都是从它开始
  7. 小程序引入的echarts过大如何解决_微信小程序中使用echarts
  8. jquerymobile iscrollview
  9. vs2005/vs2008 快捷键【转】
  10. tensorflow学习3---mnist
  11. 服务器复制不进去文件等
  12. OSChina 周二乱弹 ——流川枫与苍井空
  13. 编程之路之数据库(十)- PDO详解
  14. 微信企业号上传图片 php,C#开发微信门户及应用微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)...
  15. 【dev Cpp新手请进】dev导入ege图形库
  16. 卓训教育:如何批评孩子,正确批评孩子的方法
  17. “七夕情歌会 缘聚红豆峡” 红豆峡第15届情歌会圆满结束
  18. sct分散加载文件格式与应用
  19. (CVE-2014-0160)OpenSSL 心脏出血漏洞
  20. python熊猫弹幕_GitHub - qingyuj/danmu: Python 弹幕包 A live danmu package for python

热门文章

  1. bzoj2066: [Poi2004]Gra
  2. LVGL 8.2.0之Faded area line chart with custom division lines
  3. SOLIDWORKS仿真等幅载荷高周疲劳的分析应用
  4. python微信聊天机器人,自动翻译
  5. DOVE-----Vue.js框架入门(九)
  6. 微信公众号css实现滑动效果,基于HTML/CSS/JS微信公众号展示页面模板
  7. Web练习题---简历表页面的制作
  8. VR内容或成VR产业真正盈利点
  9. php抽奖算法,php抽奖算法
  10. 配置NTOP局域网流量监控