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>
<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;
}
}
npm install animate.css --save
main.js
import animated from 'animate.css'
Vue.use(animated)
<div class="animate__animated animate__backInUp">
</div>