1 使用插件 vue-fullpage.js
- 下载依赖npm install --save vue-fullpage.js@0.1.5
- 在 public\index.html
<!--全屏滚动插件-vue-fullpage.js的样式-->
<link
rel="stylesheet"
type="text/css"
href="https://unpkg.com/fullpage.js/dist/fullpage.min.css"
/>
3. 在 main.js
import Vue from "vue"
import 'fullpage.js/vendors/scrolloverflow';
import VueFullPage from 'vue-fullpage.js';
Vue.use(VueFullPage);
4. 组件内
<template>
<div>
<full-page :options="options" ref="page">
<div class="section">
<div class="slide">第一页1</div>
<div class="slide">第一页2</div>
<div class="slide">第一页3</div>
</div>
<div class="section">
<div class="slide">第二页</div>
</div>
<div class="section">第三页</div>
<div class="section fp-auto-height footer">
<div>底部</div>
</div>
</full-page>
</div>
</template>
<script>
export default {
data() {
return {
options: {
// key
licenseKey: "OPEN-SOURCE-GPLV3-LICENSE",
// 是否显示导航,默认为false
navigation: true,
// 是否显示横向幻灯片的导航
slidesNavigation: true,
// 横向幻灯片导航的位置,可以为top或者bottom
slidesNavPosition: "bottom",
// 横向slide幻灯片是否循环滚动
loopHorizontal: true,
// 用来控制slide幻灯片的箭头,设置为false,两侧的箭头会消失
controlArrows: false,
// 是否循环滚动,不会出现跳动,效果很平滑
continuousVertical: true,
// 是否使用插件滚动方式,设为false后,会出现浏览器自带的滚动条,将不会按页滚动
// autoScrolling: true,
// 设置每个section底部的padding,当我们要设置一个固定在底部的菜单、导航、元素等时使用
paddingBottom: "10",
// 启用自适应高度
autoHeight: true,
// 为每个section设置背景色
sectionsColor: ["#fff", "#fff", "#fff"],
// 滚动到某一屏的回调
// afterLoad: this.afterLoad
// onLeave: this.onLeave
},
time: null,
}
},
mounted() {
// this.time = setInterval(() => {
// this.$refs.page.api.moveSlideRight() // 向右滚动
// }, 15000)
},
methods: {},
destroyed() {
clearInterval(this.time)
},
}
</script>
<style lang="scss" scoped>
.footer {
background: pink;
}
</style>
⚠️ 但是有问题,有哪个大神可以解决一下
加上了fp-auto-height 但是底部的页码没有自适应,还是占用一整个页面
其次就是 第一个的滚动使用这个插件,和 定时器 滚懂到最后一页的时候,没有无缝滚动回第一页,而是倒着回到第一页。。。
但是上面的代码可以简单实现全屏滚动
2 不使用插件
<template>
<div class="big-box" ref="fullPage">
<div
ref="element"
:class="{ isShowActive: isShow }"
class="inside-box"
@mousewheel="mousewheel"
>
<!-- 滚动元素
style 也可以换成背景图片
-->
<div
v-for="(item, index) in backgroundList"
:key="index"
:style="{ backgroundColor: item.backgroundImage }"
class="scroll-box"
>
{{ item.name }}
</div>
</div>
<!-- 右侧指示器 -->
<ul class="aside-box">
<li
v-for="(item, index) in asideData"
:key="index"
@click="changeAside(index)"
>
<span :class="{ active: index === indexList }"></span>
<div class="show-tit">{{ item.title }}</div>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
element: {},
isShow: false,
run: true,
windowHeight: 0,
indexList: 0,
backgroundList: [
{
backgroundImage: "red",
name: "第一页",
},
{
backgroundImage: "green",
name: "第二页",
},
{
backgroundImage: "yellow",
name: "第三页",
},
{
backgroundImage: "pink",
name: "第四页",
},
],
asideData: [
{ title: "第一页" },
{ title: "第二页" },
{ title: "第三页" },
{ title: "第四页" },
],
}
},
computed: {
transformScroll() {
return `translateY(-${this.indexList * this.windowHeight}px)`
},
},
watch: {
element: {
handler() {
if (this.element.style) {
this.element.style.transform = this.transformScroll
}
},
immediate: true,
},
},
methods: {
mousewheel(e) {
this.isShow = false
if (this.run) {
this.run = false
this.goScroll(e)
setTimeout(() => {
this.run = true
}, 200)
}
},
next() {
if (this.indexList < 3) {
this.indexList++
}
this.element.style.transform = this.transformScroll
},
prev() {
if (this.indexList > 1 || this.indexList === 1) {
this.indexList--
}
this.element.style.transform = this.transformScroll
},
goScroll(e) {
if (e.wheelDelta < 0) {
this.next()
} else {
this.prev()
}
},
changeAside(index) {
this.isShow = true
this.indexList = index
this.element.style.transform = this.transformScroll
},
},
mounted() {
this.element = this.$refs.element
this.windowHeight = this.$refs.fullPage.clientHeight
},
}
</script>
<style lang="scss" scoped>
.content {
position: absolute;
height: 1000px;
width: 100px;
background: #fff;
}
.big-box {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
.inside-box {
width: 100%;
height: 100%;
transition: all ease-in-out 1s;
.scroll-box {
height: 100%;
background-size: cover !important;
background-position: center;
background-repeat: no-repeat;
}
}
.aside-box {
list-style: none;
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
li {
height: 14px;
width: 14px;
margin: 7px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.show-tit {
position: absolute;
font-size: 10px;
width: 45px;
right: 20px;
opacity: 0;
color: #fff;
transition: all linear 0.1s;
}
span {
border-radius: 100%;
border: #fff solid 1px;
width: 4px;
height: 4px;
display: inline-block;
background-color: #fff;
transition: all ease-in-out 0.2s;
}
&:hover span {
width: 10px;
height: 10px;
background-color: #fff;
cursor: pointer;
}
&:hover .show-tit {
opacity: 1;
}
}
}
}
.isShowActive {
transition: all 0.5s ease-in-out !important;
}
.active {
width: 12px !important;
height: 12px !important;
}
</style>