[TOC]

一、前言

使用 swiper ,参考 vant 组件库的实现

二、基础实现步骤

1. 下载 swiper

$ npm install swiper

2. 创建 Swiper 组件

// src/components/Swiper/index.vue
<template>
  <div class="swiper-container" ref="swiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide">Slide 1</div>
      <div class="swiper-slide">Slide 2</div>
      <div class="swiper-slide">Slide 3</div>
    </div>
    <!-- 如果需要分页器 -->
    <div class="swiper-pagination"></div>
  </div>
</template>

<script>
// 引入 Swiper 与它的样式
import Swiper from 'swiper'
import 'swiper/css/swiper.css'

export default {
  name: 'Swiper',

  mounted () {
    /* eslint-disable */
    // 实例化
    new Swiper(this.$el, {
      pagination: {
        el: ".swiper-pagination"
      },
    });
    /* eslint-enable */
  }
}
</script>

<style lang="scss">
.swiper-container {
  width: 100%;
  height: 180px;
}
</style>

3. 使用

// src/App.vue
<template>
  <div id="app">
    // 使用即可
    <Swiper />
  </div>
</template>

<script>
// 引入 Swiper 组件
import Swiper from '@/components/Swiper'

export default {
    name: 'App',

  components: {
    // 将 Swiper 注册为当前组件的局部组件
      Swiper
  }
}
</script>

三、优化,让组件更灵活

我们已经实现了一个最基础的 Swiper 组件。但是远远不够,我们期望这个组件能更加的灵活可配置。 比如下面这种调用情况

<Swiper :autoplay="3000" loop @change="onChange">
  <SwiperItem>1</SwiperItem>
  <SwiperItem>2</SwiperItem>
  <SwiperItem>3</SwiperItem>
</Swiper>

从上述的调用来分析,我们需要做如下支持:

  1. 支持 slot
  2. 支持 自动轮播间隔(autoplay)
  3. 支持 循环无缝轮播(loop)
  4. 支持 每一页轮播结束后触发的自定义事件 (change)

修改之后的代码

  1. src/components/Swiper/Swiper.vue ```html


2. src/components/Swiper/SwiperItem.vue
```html
<template>
  <div class="swiper-slide">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: 'SwiperItem'
}
</script>

问题1、Swiper复用时,小圆点不能动了

问题原因:new Swiper 使用的是一个 css 类选择器。当 Swiper 组件复用多次时,new Swiper 对这个元素实例化了多次。

解决办法:

  1. 方案一、new Swiper 不要使用 类选择器,使用 Id 选择器 (不要这样去用)
  2. 方案二、使用 ref 特性(推荐,首先通过 ref 去标记元素,然后使用 $refs 去获取内容)
    1. ref 标记的是普通的元素,那么后续得到的是这个元素的 DOM 对象
    2. ref 标记的是一个子组件,那么后续得到的是这个子组件的 实例 对象
  3. 方案三、Swiper 组件的根元素就是需要的 Swiper 容器,所以也可以直接去使用 $el 实例属性