vue实现页面加载动画效果


Posted in Javascript onSeptember 19, 2017

我们经常看到数据未出现时,页面中会有一条提示消息, 页面正在加载中,如何实现该效果呢 ,请看下面代码

<template>
 <section class="page" v-if="option" 
  :style="{background: option.background,color: option.color||'#fff'}"  
  :class="{'page-before': option.index < currentPage,
    'page-after': option.index > currentPage,
    'page-current': option.index === currentPage}">
  <div :class="{'all-center': option.isCenter}">
   <slot></slot>
  </div>
 </section>
 <section class="page" v-else>页面正在渲染中。。。</section>
</template>

有木有感觉很简单
下面上点干货,实现页面的动画效果

<template>
 <nav class="controller">
  <button v-if="option.arrowsType" class="prev-btn" :class="{moving:option.arrowsType === 'animate'}" @click="changePage(prevIndex)"></button>
  <ul v-if="option.navbar">
   <li v-for="index in pageNum" @click="changePage(index)" :class="{current:option.highlight && index === currentPage}" :key="'controller-'+index" :data-index="index" class="controller-item"></li>
  </ul>
  <button v-if="option.arrowsType" class="next-btn" :class="{moving:option.arrowsType === 'animate'}" @click="changePage(nextIndex)"></button>
 </nav>
</template>

<script>
export default {
 name: 'page-controller',
 props: {
 pageNum: Number,
 currentPage: Number,
 option: {
  type: Object,
  default: {
  arrowsType: 'animate',
  navbar: true,
  highlight: true,
  loop: true  //是否开启滚动循环
  }
 }
 },
 methods: {
 changePage (index) {
  this.$emit('changePage', index);
 }
 },
 computed: {
 nextIndex () {
  if (this.currentPage === this.pageNum) {
  if(this.option.loop){
   return 1
   }else{
   return this.pageNum
   }
  } else {
  return this.currentPage + 1;
  }
 },
 prevIndex () {
  if (this.currentPage === 1) {
  if(this.option.loop){
   return this.pageNum
   }else{
   return 1
   }
  } else {
  return this.currentPage - 1;
  }
 }
 },
 created () {
 if (this.option.navbar === undefined) {
  this.option.navbar = true;
 }
 },
 mounted () {
 let _this = this;
 let timer = null;
 let start = 0;
 // 滚轮处理
 function scrollHandler (direction) {
  // 防止重复触发滚动事件
  if (timer != null) {
  return;
  }
  if (direction === 'down') {
  _this.changePage(_this.nextIndex);
  } else {
  _this.changePage(_this.prevIndex);
  }
  timer = setTimeout(function() {
  clearTimeout(timer);
  timer = null;
  }, 300);
 }
 // if (Object.hasOwnProperty.call(window,'onmousewheel')) {
 if (Object.hasOwnProperty.call(window,'onmousewheel')) {
  // 监听滚轮事件
  window.addEventListener('mousewheel',function (event) { // IE/Opera/Chrome
  let direction = event.wheelDelta > 0 ? 'up':'down';
  scrollHandler(direction);
  },false);
 } else {
  window.addEventListener('DOMMouseScroll',function (event) { // Firefox
  let direction = event.detail > 0 ? 'up':'down';
  scrollHandler(direction);
  },false);
 }
 // 移动端触摸事件处理
 window.addEventListener('touchstart', function (event) {
  start = event.touches[0].clientY;
 })
 window.addEventListener('touchmove', function (event) {
  event.preventDefault();
 })
 window.addEventListener('touchend', function (event) {
  let spacing = event.changedTouches[0].clientY - start;
  let direction;  
  if (spacing > 50) {
  direction = 'up';
  scrollHandler(direction);
  } else if (spacing < -50) {
  direction = 'down';
  scrollHandler(direction);
  }
 })
 }
}
</script>

<style scoped>
.controller {
 position: fixed;
 right: 20px;
 top: 50%;
 z-index: 99;
}
.controller ul {
 transform: translate3d(0,-50%,0);
 list-style: none;
 margin: 0;
 padding: 0;
}
.controller-item {
 cursor: pointer;
 width: 20px;
 height: 20px;
 border-radius: 50%;
 margin-top: 10px;
 background-color: rgba(255, 255, 255, 0.3);
 transition: background-color 0.3s ease 0s;
}
.controller-item:hover {
 background-color: rgba(255, 255, 255, 0.7);
}
.controller-item.current {
 background-color: rgba(255, 255, 255, 1);
}
.prev-btn,.next-btn {
 cursor: pointer;
 display: block;
 text-align: center;
 width: 20px;
 height: 20px;
 position: fixed;
 left: 50%;
 margin-left: -10px;
 border: 4px solid #fff;
 background-color: transparent;
 outline: none;
}
.prev-btn {
 top: 80px;
 transform: rotate(-45deg);
 border-bottom-color: transparent;
 border-left-color: transparent;
}
.next-btn {
 bottom: 80px;
 transform: rotate(45deg);
 border-top-color: transparent;
 border-left-color: transparent;
}
.prev-btn.moving {
 animation: prev-up-down 0.7s linear 0s infinite;
}
.next-btn.moving {
 animation: next-up-down 0.7s linear 0s infinite;
}
@keyframes next-up-down {
 0% {
 transform: translate3d(0,0,0) rotate(45deg);
 }
 25% {
 transform: translate3d(0,6px,0) rotate(45deg);
 }
 50% {
 transform: translate3d(0,0,0) rotate(45deg);
 }
 75% {
 transform: translate3d(0,-6px,0) rotate(45deg);
 }
 100% {
 transform: translate3d(0,0,0) rotate(45deg);
 }
}
@keyframes prev-up-down {
 0% {
 transform: translate3d(0,0,0) rotate(-45deg);
 }
 25% {
 transform: translate3d(0,-6px,0) rotate(-45deg);
 }
 50% {
 transform: translate3d(0,0,0) rotate(-45deg);
 }
 75% {
 transform: translate3d(0,6px,0) rotate(-45deg);
 }
 100% {
 transform: translate3d(0,0,0) rotate(-45deg);
 }
}
</style>

本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。

关于vue.js组件的教程,请大家点击专题vue.js组件学习教程进行学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 实现css风格选择器(压缩后2KB)
Jan 12 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
Feb 08 Javascript
javascript实现博客园页面右下角返回顶部按钮
Feb 22 Javascript
详解JavaScript对象和数组
Dec 03 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
Apr 18 Javascript
vue.js 使用v-if v-else发现没有执行解决办法
May 15 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
Jun 02 Javascript
JavaScript登录验证基础教程
Nov 01 Javascript
vue内置指令详解
Apr 03 Javascript
JS判断字符串是否为整数的方法--简单的正则判断
Jul 23 Javascript
Vue 2.0双向绑定原理的实现方法
Oct 23 Javascript
基于JQuery实现页面定时弹出广告
May 08 jQuery
深入理解Node.js中通用基础设计模式
Sep 19 #Javascript
微信小程序媒体组件详解(视频,音乐,图片)
Sep 19 #Javascript
Javascript中将变量转换为字符串的三种方法
Sep 19 #Javascript
详解JS中的this、apply、call、bind(经典面试题)
Sep 19 #Javascript
JavaScript 中的 this 简单规则
Sep 19 #Javascript
在 Node.js 中使用原生 ES 模块方法解析
Sep 19 #Javascript
Webpack 服务器端代码打包的示例代码
Sep 19 #Javascript
You might like
PHP include_path设置技巧分享
2011/07/03 PHP
PHP类与对象中的private访问控制的疑问
2012/11/01 PHP
ThinkPHP自动填充实现无限级分类的方法
2014/08/22 PHP
微信红包随机生成算法php版
2016/07/21 PHP
window.open以post方式将内容提交到新窗口
2012/12/26 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
2013/03/04 Javascript
获取表单控件原始(初始)值的方法
2013/08/21 Javascript
javascript列表框操作函数集合汇总
2013/11/28 Javascript
window.returnValue使用方法示例介绍
2014/07/03 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
微信企业号开发之微信考勤Cookies的使用
2015/09/11 Javascript
深入学习JavaScript对象
2015/10/13 Javascript
Nodejs初级阶段之express
2015/11/23 NodeJs
Vue.js双向绑定实现原理详解
2016/12/22 Javascript
微信小程序之自定义组件的实现代码(附源码)
2018/08/02 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
JavaScript遍历数组的方法代码实例
2020/01/14 Javascript
原生js实现随机点名
2020/07/05 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
2020/07/31 Javascript
[13:55]Newbee vs Team Spirit
2018/06/07 DOTA
Python中的默认参数详解
2015/06/24 Python
Python实现简单字典树的方法
2016/04/29 Python
利用Python实现图书超期提醒
2016/08/02 Python
如何用itertools解决无序排列组合的问题
2017/05/18 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
Python实现批量执行同目录下的py文件方法
2019/01/11 Python
Python图像处理库PIL的ImageFilter模块使用介绍
2020/02/26 Python
python输出结果刷新及进度条的实现操作
2020/07/13 Python
详解CSS3中Media Queries的相关使用
2015/07/17 HTML / CSS
使用HTML5的Notification API制作web通知的教程
2015/05/08 HTML / CSS
英国、欧洲和全球租车服务:Avis英国
2016/08/29 全球购物
英国领先的在线礼品店:Getting Personal
2019/09/24 全球购物
现金会计岗位职责
2013/12/05 职场文书
总经理助理岗位职责
2015/01/31 职场文书
电力安全学习心得体会
2016/01/18 职场文书
Java方法重载和方法重写的区别到底在哪?
2021/06/11 Java/Android