直入主題:vue項目中想做一個全屏翻滾的效果,vue-fullpage 就很不錯
下面介紹vue-fullpage 的使用方法,這里封裝成了vue的一個指令的形式來進行使用
1、安裝vue-fullpage,最新版就可以
npm install vue-fullpage -S
2、入口文件main.js引入
import Vue from 'vue' // vue全屏滾動使用 import VueFullpage from './utils/VueFullpage.js' Vue.use(VueFullpage)
3、main.js同級下有文件utils/VueFullpage.js

'use strict'; var fullpage = {}; var opt = { start: 0, duration: 500, loop: false, dir: 'v', der: 0.1, movingFlag: false, preventWechat: false, needInitAfterUpdated: false, beforeChange: function(data) {}, afterChange: function(data) {} }; fullpage.install = function(Vue, options) { var that = fullpage; Vue.directive('fullpage', { inserted: function(el, binding, vnode) { var opts = binding.value || {}; that.init(el, opts, vnode); }, componentUpdated: function(el, binding, vnode) { if (!that.o.needInitAfterUpdated) { return; } var opts = binding.value || {}; that.init(el, opts, vnode); } }); Vue.directive('animate', { inserted: function(el, binding, vnode) { if (binding.value) { that.initAnimate(el, binding, vnode); } } }); }; fullpage.initAnimate = function(el, binding, vnode) { var that = fullpage; var vm = vnode.context; var aminate = binding.value; el.style.opacity = '0'; vm.$on('toogle_animate', function(curIndex) { var parent = el.parentNode; while (parent.getAttribute('data-id') === null) { parent = parent.parentNode; } var curPage = +parent.getAttribute('data-id'); if (curIndex === curPage) { that.addAnimated(el, aminate); } else { el.style.opacity = '0'; that.removeAnimated(el, aminate); } }); }; fullpage.addAnimated = function(el, animate) { var delay = animate.delay || 0; el.classList.add('animated'); window.setTimeout(function() { el.style.opacity = '1'; el.classList.add(animate.value); }, delay); }; fullpage.removeAnimated = function(el, animate) { var classes = el.getAttribute('class'); if (classes && classes.indexOf('animated') > -1) { el.classList.remove(animate.value); } }; fullpage.assignOpts = function(option) { var that = fullpage; var o = option || {}; for (var key in opt) { if (!o.hasOwnProperty(key)) { o[key] = opt[key]; } } that.o = o; }; fullpage.initScrollDirection = function() { if (this.o.dir !== 'v') { this.el.classList.add('fullpage-wp-h'); } }; fullpage.init = function(el, options, vnode) { var that = fullpage; that.assignOpts(options); that.vm = vnode.context; that.vm.$fullpage = that; that.curIndex = that.o.start; that.startY = 0; that.o.movingFlag = false; that.el = el; that.el.classList.add('fullpage-wp'); that.parentEle = that.el.parentNode; that.parentEle.classList.add('fullpage-container'); that.pageEles = that.el.children; that.total = that.pageEles.length; that.initScrollDirection(); window.setTimeout(function() { that.width = that.parentEle.offsetWidth; that.height = that.parentEle.offsetHeight; for (var i = 0; i < that.pageEles.length; i++) { var pageEle = that.pageEles[i]; pageEle.setAttribute('data-id', i); pageEle.classList.add('page'); pageEle.style.width = that.width + 'px'; pageEle.style.height = that.height + 'px'; that.initEvent(pageEle); } that.moveTo(that.curIndex, false); }, 0); }; fullpage.initEvent = function(el) { var that = fullpage; that.prevIndex = that.curIndex; el.addEventListener('touchstart', function(e) { if (that.o.movingFlag) { return false; } that.startX = e.targetTouches[0].pageX; that.startY = e.targetTouches[0].pageY; }); el.addEventListener('touchend', function(e) { if (that.o.movingFlag) { return false; } var dir = that.o.dir; var sub = dir === 'v' ? (e.changedTouches[0].pageY - that.startY) / that.height : (e.changedTouches[0].pageX - that.startX) / that.width; var der = sub > that.o.der ? -1 : sub < -that.o.der ? 1 : 0; // that.curIndex推遲到moveTo執行完之后再更新 var nextIndex = that.curIndex + der; if (nextIndex >= 0 && nextIndex < that.total) { that.moveTo(nextIndex, true); } else { if (that.o.loop) { nextIndex = nextIndex < 0 ? that.total - 1 : 0; that.moveTo(nextIndex, true); } else { that.curIndex = nextIndex < 0 ? 0 : that.total - 1; } } }); if (that.o.preventWechat) { el.addEventListener('touchmove', function(e) { e.preventDefault(); }); } }; fullpage.moveTo = function(curIndex, anim) { var that = fullpage; var dist = that.o.dir === 'v' ? curIndex * -that.height : curIndex * -that.width; that.o.movingFlag = true; var flag = that.o.beforeChange(that.prevIndex, curIndex); if (flag === false) { // 重置movingFlag that.o.movingFlag = false; return false; } that.curIndex = curIndex; if (anim) { that.el.classList.add('anim'); } else { that.el.classList.remove('anim'); } that.move(dist); window.setTimeout(function() { that.o.afterChange(that.prevIndex, curIndex); that.o.movingFlag = false; that.prevIndex = curIndex; that.vm.$emit('toogle_animate', curIndex); }, that.o.duration); }; fullpage.move = function(dist) { var xPx = '0px'; var yPx = '0px'; if (this.o.dir === 'v') { yPx = dist + 'px'; } else { xPx = dist + 'px'; } this.el.style.cssText += '-webkit-transform:translate3d(' + xPx + ', ' + yPx + ', 0px);transform:translate3d(' + xPx + ', ' + yPx + ', 0px);'; }; if (window.Vue) { window.VueFullpage = fullpage; Vue.use(fullpage); } window.VueFullpage = fullpage; export default fullpage;
4、vueFullPage.vue使用頁

<template> <!-- vue全屏滾動 --> <!-- 使用方法:安裝vue-fullpage,until中放入VueFullpage.js, main.js中引入 --> <!-- 如出現空白頁時是因為數據還沒加載完就渲染了v-fullpage,數據請求成功后在最外層加個 v-if展示判斷 --> <div class="fullPage"> <!-- 滾動區域容器 --> <div class="fullpage-container"> <div class="fullpage-wp" v-fullpage="opts" v-if="isFullPage"> <div class="page pageFirst"> <img class="pageBanner" :src="reportBg1"> <div class="dataCont"> <p>第一頁</p> </div> </div> <div class="page"> <img class="pageBanner" :src="reportBg2"> <div class="dataCont"> <p>第二頁</p> </div> </div> <div class="page"><img class="pageBanner" :src="reportBg3"> <div class="dataCont"> <p>第三頁</p> </div> </div> <div class="page"><img class="pageBanner" :src="reportBg4"> <div class="dataCont"> <p>第四頁</p> </div> </div> </div> </div> <!-- 滾動區域容器 --> </div> </template> <script> import 'vue-fullpage/vue-fullpage.css'; import "@/assets/css/pages/fullpage.scss"; import Vue from 'vue' export default { name: "vuefullPage", components: {}, data() { return { isFullPage: true, //page里加v-if判斷時避免空白頁,請求接口完成后渲染頁data-id按順序排列 opts: { start: 0, loop: false, duration: 500, stopPageScroll: true, loopHorizontal: true, beforeChange: function(prev, next) {}, afterChange: function(prev, next) {} }, //上下滑動大背景 reportBg1: require("@/assets/imgs/reportBg1.png"), reportBg2: require("@/assets/imgs/reportBg2.png"), reportBg3: require("@/assets/imgs/reportBg3.png"), reportBg4: require("@/assets/imgs/reportBg4.png"), } }, mounted() { let that = this; }, watch: {}, methods: {} } </script> <style scoped lang="less"> .fullpage-container { position: absolute; left: 0; top: 0; width: 100%; height: 100%; } .fullPage { height: 100%; } .page { .dataCont { position: absolute; top: 10%; left: 7%; } } </style>