首发于前端之旅

一文详解vue-awesome-swiper

Swiper简介

Swiper是纯javascript打造的滑动特效插件,能够实现触屏焦点图、触屏Tab切换、触屏多图切换等常用效果。vue-awesome-swiper是基于swiper封装的vue插件, 版本对应关系如下:

引入

1,安装

npm install swiper vue-awesome-swiper --save 

2,CDN

<link rel="stylesheet" href="path/to/swiper.css"/>
<script type="text/javascript" src="path/to/swiper.js"></script>
<script type="text/javascript" src="path/to/vue.min.js"></script>
<script type="text/javascript" src="path/to/dist/vue-awesome-swiper.js"></script>
<script type="text/javascript">
    Vue.use(window.VueAwesomeSwiper)
</script>

注册

1,在main.js中全局注册

import VueAwesomeSwiper from 'vue-awesome-swiper';
Vue.use(VueAwesomeSwiper);

2,在.vue文件中局部注册

import { swiper, swiperSlide } from 'vue-awesome-swiper';
components: {
    swiper,
    swiperSlide
}

引入样式

import 'swiper/dist/css/swiper.css'; 

要在webpack.base.conf.js的rules数组中配置

{
    test: /\.css$/,
    use: [
        {
            loader: "style-loader"
        }, {
            loader: "css-loader"
        }
    ]
}

不然会报错:

ERROR in ./node_modules/swiper/dist/css/swiper.css

Module parse failed: Unexpected token (12:0)

You may need an appropriate loader to handle this file type.

| * Released on: February 22, 2019

| */

| .swiper-container {

| margin: 0 auto;

| position: relative;

@ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/pages/walMart/giftCardList.vue 67:0-37

@ ./src/pages/walMart/giftCardList.vue

@ ./src/routes.js

@ ./src/main.js

@ multi ./build/dev-client ./src/main.js

使用方式

<template>
    <swiper ref="mySwiper" :options="swiperOptions">
        <swiper-slide>Slide 1</swiper-slide>
        <swiper-slide>Slide 2</swiper-slide>
        <swiper-slide>Slide 3</swiper-slide>
        <swiper-slide>Slide 4</swiper-slide>
        <swiper-slide>Slide 5</swiper-slide>
        <div class="swiper-pagination" slot="pagination"></div>
    </swiper>
</template>

<script>
    export default {
        name: 'carrousel',
        data() {
            return {
                swiperOptions: {
                    autoplay: true, // 自动轮播  
                    speed: 1000,   // 轮播速度
                    pagination: {
                        el: '.swiper-pagination'
                    },
                    on: {
                        slideChangeTransitionEnd: function() {
                            // ...
                        }
                    }
                    // Some Swiper option/callback...
                }
            }
        },
        computed: {
            swiper() {
                return this.$refs.mySwiper.swiper
            }
        },
        mounted() {
            console.log('Current Swiper instance object', this.swiper)
            this.swiper.slideTo(3, 1000, false)
        }
    }
</script> 

swiper配置选项可以参考:swiper.com.cn/api/grid/


Swiper component API

<!-- All events/props support camelCase or kebab-case. -->
<swiper
        :options="swiperOptionsObject"
        :auto-update="true"
        :auto-destroy="true"
        :delete-instance-on-destroy="true"
        :cleanup-styles-on-destroy="true"
        @ready="handleSwiperReadied"
        @click-slide="handleClickSlide"
/>

<!-- vue-awesome-swiper converts all Swiper events into component/directive events, e.g.: -->
<swiper
        @slide-change-transition-start="onSwiperSlideChangeTransitionStart"
        @slideChangeTransitionStart="onSwiperSlideChangeTransitionStart"
        @slideChangeTransitionEnd="..."
        @transitionStart="..."
        ...
/>


interface IProps {
    // Auto update swiper when vue component `updated`
    autoUpdate?: boolean // default: true
    // Auto destroy swiper when vue component 'beforeDestroy'
    autoDestroy?: boolean // default: true
    
    // swiper.destroy's params
    // swiper.destroy(deleteInstanceOnDestroy, cleanupStylesOnDestroy)
    deleteInstanceOnDestroy?: boolean // default: true
    cleanupStylesOnDestroy?: boolean // default: true
}

// `@ready` event will emit when the Swiper instance mounted
function handleSwiperReadied(swiper: Swiper) {
    console.log('Swiper was munted!', swiper)
}

// `@click-slide` event has special treatment for Swiper's loop mode, which is still available in loop mode
function handleClickSlide(index: number, reallyIndex: number | null) {
    console.log('Click slide!', index, reallyIndex)
}

slideChangeTransitionEnd等监听回调API也可以直接写在swiperOptions的on属性里面。

swiper使用注意事项:

1,swiper设置loop循环无效

swiper设置loop循环无效,而且会使原本的手动滑动失效,这是因为最新的版本已经将loop: true替换为了autoplay: true,对于网上说的异步数据的问题是不存在的,自动轮播到每一帧可以异步请求后端数据再刷新。

2,事件监听回调

事件的话还是用on监听回调,不建议用@click来写点击事件,开启loop模式后点击是会失效的。配置项放在swiperOptions里面的,在on中写上tap的回调,可以实现slide的点击回调,使用click的话在移动端是有延迟的。

swiperOption: {
    // ...
    on: {
        tap() {
            // ...
        },
    },
}

3,this的指向问题

在on回调方法中this指向swiper对象,其他方法中需要使用this.$refs.mySwiper.swiper来引用(例如this.$refs.mySwiper.swiper.slideTo(index, 0);)。那么怎么在on回调方法中引用vue实例呢?在data中定义一个局部变量指向this,或者定义一个全局变量,然后在created中将其赋值为this。

4,样式污染

不要直接使用swiper-slide定义样式,单独写一个唯一的class,然后使用该class定义样式,保证不污染其他使用swiper的页面

<swiper-slide class="coupon-swiper-slide" v-for="(couponItem, index) in unUsedCouponArray" :key="index">
    <div class="qrcode-img-content">
        <img :src="couponItem.qrcodeImgUrl" class="bar-img" v-if="couponItem.qrcodeImgUrl.length > 0" />
        <p class="coupon-num" v-show="currentIndex === index">{{ couponItem.codeNo }}</p>
    </div>
</swiper-slide>


.coupon-swiper-slide {
 width: 100%;
 text-align: center;
 font-size: 18px;
 /* background: #fff; */
 display: -webkit-box;
 display: -ms-flexbox;
 display: -webkit-flex;
 display: flex;
 -webkit-box-pack: center;
 -ms-flex-pack: center;
 -webkit-justify-content: center;
 justify-content: center;
 -webkit-box-align: center;
 -ms-flex-align: center;
 -webkit-align-items: center;
 align-items: center;
 transition: 300ms;
}


.coupon-swiper-slide:not(.swiper-slide-active) {
 transform: scale(0.8);
}

5,在Android手机滑动没有放大效果

在../common/css/swiper.css文件中修改

.swiper-container-android .swiper-slide,
.swiper-wrapper {
 /*-webkit-transform: translate3d(0px, 0, 0);*/
  /*transform: translate3d(0px, 0, 0);*/
}

编辑于 2020-03-31 17:46