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 相关文章推荐
讲两件事:1.this指针的用法小探. 2.ie的attachEvent和firefox的addEventListener在事件处理上的区别
Apr 12 Javascript
JavaScript 语法集锦 脚本之家基础推荐
Nov 15 Javascript
JS面向对象编程 for Cookie
Sep 19 Javascript
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
Oct 21 Javascript
JavaScript数组去重的两种方法推荐
Apr 05 Javascript
用JS动态改变表单form里的action值属性的两种方法
May 25 Javascript
JavaScript实现时间倒计时跳转(推荐)
Jun 28 Javascript
js正则表达式惰性匹配和贪婪匹配用法分析
Dec 26 Javascript
jQuery按需加载轮播图(web前端性能优化)
Feb 17 Javascript
使用原生js+canvas实现模拟心电图的实例
Sep 20 Javascript
vue.js vue-router如何实现无效路由(404)的友好提示
Dec 20 Javascript
vue-cli3.X快速创建项目的方法步骤
Nov 14 Javascript
深入理解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 在windows下配置虚拟目录的方法介绍
2013/06/26 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
浅谈php中的访问修饰符private、protected、public的作用范围
2016/11/20 PHP
javascript引用对象的方法
2007/01/11 Javascript
jQuery模拟超链接点击效果代码
2013/04/21 Javascript
javascript 手动给表增加数据的小例子
2013/07/10 Javascript
js生成随机数之random函数随机示例
2013/12/20 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
使用jQuery实现返回顶部
2015/01/26 Javascript
NodeJs中的VM模块详解
2015/05/06 NodeJs
jQuery实现的简单提示信息插件
2015/12/08 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
BootStrap 模态框实现刷新网页并关闭功能
2017/01/04 Javascript
Nodejs+Socket.io实现通讯实例代码
2017/02/13 NodeJs
基于Vue生产环境部署详解
2017/09/15 Javascript
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
gulp安装以及打包合并的方法教程
2017/11/19 Javascript
webpack+vue-cil中proxyTable处理跨域的方法
2018/07/20 Javascript
Vue指令实现OutClick的示例
2020/11/16 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
[03:48]DOTA2完美大师赛主赛事第二日精彩集锦
2017/11/24 DOTA
Python3.x版本中新的字符串格式化方法
2015/04/24 Python
基于python if 判断选择结构的实例详解
2019/05/06 Python
Pycharm Available Package无法显示/安装包的问题Error Loading Package List解决
2020/09/18 Python
欧洲最大的预定车位市场:JustPark
2020/01/06 全球购物
什么是唯一索引
2015/07/05 面试题
点菜员岗位职责范本
2014/02/14 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
感恩父母的演讲稿
2014/05/06 职场文书
经典团队口号
2014/06/06 职场文书
解除劳动关系协议书2篇
2014/11/28 职场文书
工作失误检讨书
2015/01/26 职场文书
五一晚会主持词
2015/07/01 职场文书
消费者投诉书范文
2015/07/02 职场文书
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL