vue使用seiper-animate
前言:
Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端,能实现触屏焦点图、触屏Tab切换、触屏轮播图切换等常用效果,开源、免费、稳定、使用简单、功能强大,是架构移动终端网站的重要选择。
animate.css 是一个可在您的Web项目中使用的即用型跨浏览器动画库
使用
本项目使用 animate.css 3.7版本 ,vue-awesome-swiper 4.1.1版本 swiper 6.5.6版本
-
第一步
npm install swiper vue-awesome-swiper@4.1.1 --save
npm install animate.css@3.7
-
第二步在main.js引入swiper
import VueAwesomeSwiper from 'vue-awesome-swiper' import 'swiper/swiper.less' Vue.use(VueAwesomeSwiper, /* { default options with global component } */ )
分别引入 vue-awesome-swiper,以及swiper的样式文件,将VueAwesomeSwiper挂载到Vue上。 这里之所以引入swiper/swiper.less 是因为我的项目中使用的是 less编译器
-
第三步在main.js中引入animate.css
const animated = require('animate.css'); or import animated from "animate.css" Vue.use(animated)
-
第四步,在项目中使用 swiper
<template> <div class="index-container"> <swiper :options="swiperOptions"> <swiper-slide class="swiper-slide swiper-slide1"> Slide 1 </swiper-slide> <swiper-slide class="swiper-slide swiper-slide2"> Slide 2 </swiper-slide> <swiper-slide class="swiper-slide swiper-slide3">Slide 3</swiper-slide> <swiper-slide class="swiper-slide swiper-slide4">Slide 4</swiper-slide> <swiper-slide class="swiper-slide swiper-slide5">Slide 5</swiper-slide> </swiper> </div> </template> data() { let that = this; return { //初始化swiper swiperOptions: { direction: "vertical", initialSlide: 0, }, }; }, .index-container { height: 100%; .swiper-container { width: 100%; height: 100%; .swiper-slide { width: 100%; height: 100% !important; } } }
此时 swiper-slide已经能够滑动 , 但是不能使用swiper-animate动画 ,比如:
<swiper-slide class="swiper-slide swiper-slide1"> <div class="ani" swiper-animate-effect="fadeIn" swiper-animate-duration="1.5s" swiper-animate-delay="5s" ></div> </swiper-slide>
给div添加 ani 样式,然后根据swiper提供的swiper-animate动画属性添加在要运动的元素上,但并没有效果。
swiper-animate官网提供的教程中说:
-
使用Swiper Animate需要先加载swiper.animate.min.js和animate.min.css。
-
初始化时隐藏元素并在需要的时刻开始动画。
<script> var mySwiper = new Swiper ('.swiper-container', { on:{ init: function(){ swiperAnimateCache(this); //隐藏动画元素 swiperAnimate(this); //初始化完成开始动画 }, slideChangeTransitionEnd: function(){ swiperAnimate(this); //每个slide切换结束时也运行当前slide动画 //this.slides.eq(this.activeIndex).find('.ani').removeClass('ani'); 动画只展现一次,去除ani类名 } } }) </script>
- 在需要运动的元素上面增加类名 ani ,和其他的类似插件相同
<div class="swiper-slide"> <p class="ani" swiper-animate-effect="fadeInUp" swiper-animate-duration="0.5s" swiper-animate-delay="0.3s">内容</p> </div>
由此可以看到,我们已经完成了完成了第一步中的加载 animate.css和第三步添加ani 类名,但是我们的项目中还缺少swiper.animate.min.js , 我们从官网下载 swiper.animate1.0.3.min.js这个文件,把这个文件放到项目的
assets
目录或者其他存静态资源的目录中,在main.js
中引入并将其挂载到 Vue的原型上import { swiperAnimateCache, swiperAnimate, clearSwiperAnimate } from "@/assets/swiper.animate1.0.3.min.js" Vue.prototype.$swiperAnimateCache = swiperAnimateCache Vue.prototype.$swiperAnimate = swiperAnimate Vue.prototype.$clearSwiperAnimate = clearSwiperAnimate
然后在文件中,添加swiper初始化动画的方法
data() { let that = this; return { swiperOptions: { direction: "vertical", initialSlide: 0, on: { init: function () { that.$swiperAnimateCache(this); //隐藏动画元素 that.$swiperAnimate(this); //初始化完成开始动画 }, slideChange: function () { that.$swiperAnimate(this); //每个slide切换结束时也运行当前slide动画 //that.slides.eq(this.activeIndex).find('.ani').removeClass('ani'); 动画只展现一次,去除ani类名 }, }, }, }; },
我们再次刷新页面,发现动画还是不能执行,并且报错找不到我们引入的
swiper.animate1.0.3.min.js
的方法,原因是因为swiper.animate1.0.3.min.js
没有AMD规范,我们看一下文件的源码//本插件由www.swiper.com.cn提供 //版本1.03 function swiperAnimateCache(a) { for (j = 0; j < a.slides.length; j++) for (allBoxes = a.slides[j].querySelectorAll(".ani"), i = 0; i < allBoxes.length; i++) allBoxes[i].attributes["style"] ? allBoxes[i].setAttribute("swiper-animate-style-cache", allBoxes[i].attributes["style"].value) : allBoxes[i].setAttribute("swiper-animate-style-cache", " "), allBoxes[i].style.visibility = "hidden" } function swiperAnimate(a) { clearSwiperAnimate(a); var b = a.slides[a.activeIndex].querySelectorAll(".ani"); for (i = 0; i < b.length; i++) b[i].style.visibility = "visible", effect = b[i].attributes["swiper-animate-effect"] ? b[i].attributes["swiper-animate-effect"].value : "", b[i].className = b[i].className + " " + effect + " " + "animated", style = b[i].attributes["style"].value, duration = b[i].attributes["swiper-animate-duration"] ? b[i].attributes["swiper-animate-duration"].value : "", duration && (style = style + "animation-duration:" + duration + ";-webkit-animation-duration:" + duration + ";"), delay = b[i].attributes["swiper-animate-delay"] ? b[i].attributes["swiper-animate-delay"].value : "", delay && (style = style + "animation-delay:" + delay + ";-webkit-animation-delay:" + delay + ";"), b[i].setAttribute("style", style) } function clearSwiperAnimate(a) { for (j = 0; j < a.slides.length; j++) for (allBoxes = a.slides[j].querySelectorAll(".ani"), i = 0; i < allBoxes.length; i++) allBoxes[i].attributes["swiper-animate-style-cache"] && allBoxes[i].setAttribute("style", allBoxes[i].attributes["swiper-animate-style-cache"].value), allBoxes[i].style.visibility = "hidden", allBoxes[i].className = allBoxes[i].className.replace("animated", " "), allBoxes[i].attributes["swiper-animate-effect"] && (effect = allBoxes[i].attributes["swiper-animate-effect"].value, allBoxes[i].className = allBoxes[i].className.replace(effect, " ")) }
因此,我们直接 import导入是不可以的, 改造后的代码如下
export function swiperAnimateCache() { const allBoxes = window.document.documentElement.querySelectorAll('.ani') for (var i = 0; i < allBoxes.length; i++) { allBoxes[i].attributes['style'] ? allBoxes[i].setAttribute('swiper-animate-style-cache', allBoxes[i].attributes['style'].value) : allBoxes[i].setAttribute('swiper-animate-style-cache', ' ') allBoxes[i].style.visibility = 'hidden' } } export function swiperAnimate(a) { clearSwiperAnimate() var b = a.slides[a.activeIndex].querySelectorAll('.ani') for (var i = 0; i < b.length; i++) { b[i].style.visibility = 'visible' const effect = b[i].attributes['swiper-animate-effect'] ? b[i].attributes['swiper-animate-effect'].value : '' b[i].className = b[i].className + ' ' + effect + ' ' + 'animated' const duration = b[i].attributes['swiper-animate-duration'] ? b[i].attributes['swiper-animate-duration'].value : '' // duration && style const delay = b[i].attributes['swiper-animate-delay'] ? b[i].attributes['swiper-animate-delay'].value : '' const style = b[i].attributes['style'].value + 'animation-duration:' + duration + ';-webkit-animation-duration:' + duration + ';' + 'animation-delay:' + delay + ';-webkit-animation-delay:' + delay + ';' // delay && (style = style ) b[i].setAttribute('style', style) } } export function clearSwiperAnimate() { var allBoxes = window.document.documentElement.querySelectorAll('.ani') for (var i = 0; i < allBoxes.length; i++) { allBoxes[i].attributes['swiper-animate-style-cache'] && allBoxes[i].setAttribute('style', allBoxes[i].attributes['swiper-animate-style-cache'].value) allBoxes[i].style.visibility = 'hidden' allBoxes[i].className = allBoxes[i].className.replace('animated', ' ') const effectValue = allBoxes[i].attributes['swiper-animate-effect'].value /* eslint-disable-next-line */ allBoxes[i].attributes['swiper-animate-effect'] && (effectValue, allBoxes[i].className = allBoxes[i].className.replace(effectValue, ' ')) } }
直接覆盖原来的文件就可以了。此时我们再次刷新页面发现页面的动画就可以执行了
注意的点
-
给元素添加类名 ani ,ani的样式必须是绝对定位
.ani{ position:absolute }
-
必须给Swiper设置高度铺满屏幕 (也可以根据项目需要自行设置宽高)
.swiper-container { width: 100%; height: 100%; .swiper-slide { width: 100%; height: 100% !important; } }
-
vue中单独使用animate.css
-
npm install animate.css --save
-
main.js import animated from 'animate.css' Vue.use(animated)
-
<div class="animate__animated animate__backInUp"> </div>