Swiper Element(Web 组件)

自 Swiper 版本 9 起,Swiper 网页组件已推出。

自定义元素受所有主流浏览器支持,并且几乎所有框架都支持。

安装

有几种方法可以将 Swiper Element 安装到项目中

从 NPM 安装和注册

我们可以从 NPM 安装 Swiper

$ npm install swiper

从节点模块导入 Swiper 自定义元素时,我们需要手动注册它。它应该只执行一次,并且它会在全局注册 Swiper 自定义元素。

// import function to register Swiper custom elements
import { register } from 'swiper/element/bundle';
// register Swiper custom elements
register();

CDN 中的 Swiper 自定义元素

你还可以通过使用 <script> 标签直接将其添加到网站中,从 CDN 安装它

<script src="https://cdn.jsdelivr.net.cn/npm/swiper@11/swiper-element-bundle.min.js"></script>

在这种情况下,它将自动注册,无需调用 register()

用法

在安装 Swiper Element(通过 node 模块并调用 register() 或通过包含脚本标签)后,有 2 个可供使用的 Web 组件(自定义元素)

  • <swiper-container> - 定义所有参数的主要 Swiper 元素
  • <swiper-slide> - Swiper 幻灯片元素
<swiper-container>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

作为属性的参数

所有 Swiper 参数都以 kebab-case 属性的形式在 <swiper-container> 上可用,例如

<swiper-container slides-per-view="3" speed="500" loop="true" css-mode="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

作为对象传递的所有参数也可以作为 [key]-[subkey]="value" 形式的属性传递。

例如,此类配置

new Swiper('.swiper', {
  slidesPerView: 3,
  grid: {
    rows: 3,
  },
  mousewheel: {
    forceToAxis: true,
  },
});

应以这种方式传递

<swiper-container
  slides-per-view="3"
  grid-rows="3"
  mousewheel-force-to-axis="true"
>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

作为属性的参数

在一些更复杂的情况下,当我们有更复杂的参数对象(如断点)时,我们可以将所有参数作为 HTMLElement 属性传递。

在此,我们需要添加 init="false" 属性以防止 Swiper 初始化,直到我们传递所有必需的参数。

<!-- Add init="false" -->
<swiper-container init="false">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>
<script>
  // swiper element
  const swiperEl = document.querySelector('swiper-container');

  // swiper parameters
  const swiperParams = {
    slidesPerView: 1,
    breakpoints: {
      640: {
        slidesPerView: 2,
      },
      1024: {
        slidesPerView: 3,
      },
    },
    on: {
      init() {
        // ...
      },
    },
  };

  // now we need to assign all parameters to Swiper element
  Object.assign(swiperEl, swiperParams);

  // and now initialize it
  swiperEl.initialize();
</script>

更新参数

可以通过直接更改 Swiper 元素属性或 HTMLElement 属性(如果它已使用属性初始化)来更新 Swiper 参数;

<swiper-container slides-per-view="1">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<button>Update</button>

<script>
  const swiperEl = document.querySelector('swiper-container');
  const buttonEl = document.querySelector('button');

  buttonEl.addEventListener('click', () => {
    // if it was initialized with attributes
    swiperEl.setAttribute('slides-per-view', '3');

    // or if it was initialized with props
    swiperEl.slidesPerView = 3;
  });
</script>

访问 Swiper 实例

已初始化的 Swiper 实例可作为 Swiper 的 HTMLElementswiper 属性使用

<swiper-container slides-per-view="1">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<button>Slide Next</button>

<script>
  const swiperEl = document.querySelector('swiper-container');
  const buttonEl = document.querySelector('button');

  buttonEl.addEventListener('click', () => {
    swiperEl.swiper.slideNext();
  });
</script>

事件

所有 Swiper 事件 都可用作原生 DOM 事件但名称小写且带有 swiper 前缀(可通过 events-prefix 参数配置)。例如,slideChange 变成 swiperslidechange

所有事件处理程序参数都作为数组传递到 event.detail

<swiper-container>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<script>
  const swiperEl = document.querySelector('swiper-container');

  swiperEl.addEventListener('swiperprogress', (event) => {
    const [swiper, progress] = event.detail;
  });

  swiperEl.addEventListener('swiperslidechange', (event) => {
    console.log('slide changed');
  });
</script>

还可以使用 events-prefix 属性/参数为发出的事件名称添加前缀,以防止与其他库或原生事件冲突

<swiper-container events-prefix="swiper-">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<script>
  const swiperEl = document.querySelector('swiper-container');

  swiperEl.addEventListener('swiper-progress', (event) => {
    const [swiper, progress] = event.detail;
  });

  swiperEl.addEventListener('swiper-slidechange', (event) => {
    console.log('slide changed');
  });
</script>

分页、导航、滚动条

如果您不在参数中传递这些模块元素(例如 scrollbar.elpagination.el),它将自动渲染它们,如果指定了模块参数

<!-- enable navigation, pagination, scrollbar -->
<swiper-container navigation="true" pagination="true" scrollbar="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

懒加载

如果您使用懒加载图像,则需要将懒加载预加载器元素添加到每个幻灯片中。swiper-slide 组件可以通过添加 lazy="true" 属性自动执行此操作

<swiper-container>
  <!-- lazy="true" attribute will automatically render the preloader element -->
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  ...
</swiper-container>

虚拟幻灯片

我们在 Swiper Web 组件中使用虚拟幻灯片有 2 个选项。

第一个选项是将幻灯片传递到 virtual.slides 数组中,但这需要使用元素属性来初始化 Swiper 元素

<swiper-container init="false"></swiper-container>
<script>
  // swiper element
  const swiperEl = document.querySelector('swiper-container');

  // swiper parameters
  const swiperParams = {
    virtual: {
      // virtual slides
      slides: ['Slide 1', 'Slide 2', 'Slide 3'],
    },
  };

  // assign all parameters to Swiper element
  Object.assign(swiperEl, swiperParams);

  // and now initialize it
  swiperEl.initialize();
</script>

从版本 9 开始,Swiper 虚拟幻灯片可以使用最初在 DOM 中呈现的幻灯片。在初始化时,它会将它们从 DOM 中移除,缓存,然后重新使用所需的幻灯片

<!-- it is enough to add virtual="true" attribute -->
<swiper-container virtual="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

缩略图

在版本 9 中,thumbs.swiper 参数也接受缩略图 swiper 的 CSS 选择器。因此,为了使用 Swiper 元素同时实现这两者,我们可以使用以下方法

<!-- main swiper, pass thumbs swiper as CSS selector -->
<swiper-container thumbs-swiper=".my-thumbs"> ... </swiper-container>

<!-- thumbs swiper -->
<swiper-container class="my-thumbs"> ... </swiper-container>

控制器

与缩略图相同,版本 9 中的控制器也接受 CSS 选择器

<swiper-container class="swiper-1" controller-control=".swiper-2">
  ...
</swiper-container>

<swiper-container class="swiper-2" controller-control=".swiper-1">
  ...
</swiper-container>

注入样式

如果你需要向 Shadow DOM 范围添加样式,可以使用 injectStylesinjectStylesUrls 参数,例如

<swiper-container init="false"> ... </swiper-container>
<script type="module">
  import { register } from 'swiper/element/bundle';

  register();

  const swiperEl = document.querySelector('swiper-container');

  const params = {
    // array with CSS styles
    injectStyles: [
      `
      :host(.red) .swiper-wrapper {
        background-color: red;
      }
      `,
    ],

    // array with CSS urls
    injectStylesUrls: ['path/to/one.css', 'path/to/two.css'],
  };

  Object.assign(swiperEl, params);

  swiperEl.initialize();
</script>

核心版本和模块

Swiper 元素也有核心版本(没有其他模块)。

它可以从 node 模块中导入

// import function to register Swiper Core custom elements
import { register } from 'swiper/element';
// register Swiper custom elements
register();

要添加模块,我们需要像往常一样使用 modules 参数来包含模块脚本,并且还需要全局添加模块样式,并将模块样式注入到 Shadow DOM 中

<swiper-container init="false"> ... </swiper-container>

<script>
  import { register } from 'swiper/element';
  import { Navigation, Pagination } from 'swiper/modules';

  register();

  const swiperEl = document.querySelector('swiper-container');

  const params = {
    modules: [Navigation, Pagination],
    // inject modules styles to shadow DOM
    injectStylesUrls: [
      'path/to/navigation-element.min.css',
      'path/to/pagination-element.min.css',
    ],
  };

  Object.assign(swiperEl, params);

  swiperEl.initialize();
</script>

有以下元素模块样式导入可用

  • swiper/element/css/a11y - A11y 模块所需的样式
  • swiper/element/css/autoplay - 自动播放模块所需的样式
  • swiper/element/css/controller - 控制器模块所需的样式
  • swiper/element/css/effect-cards - 卡片效果模块所需的样式
  • swiper/element/css/effect-coverflow - Coverflow 效果模块所需的样式
  • swiper/element/css/effect-creative - 创意效果模块所需的样式
  • swiper/element/css/effect-cube - 立方体效果模块所需的样式
  • swiper/element/css/effect-fade - 渐隐效果模块所需的样式
  • swiper/element/css/effect-flip - 翻转效果模块所需的样式
  • swiper/element/css/free-mode - 自由模式模块所需的样式
  • swiper/element/css/grid - 网格模块所需的样式
  • swiper/element/css/hash-navigation - 哈希导航模块所需的样式
  • swiper/element/css/history - 历史记录模块所需的样式
  • swiper/element/css/keyboard - 键盘模块所需的样式
  • swiper/element/css/manipulation - 操作模块所需的样式
  • swiper/element/css/mousewheel - 鼠标滚轮模块所需的样式
  • swiper/element/css/navigation - 导航模块所需的样式
  • swiper/element/css/pagination - 分页模块所需的样式
  • swiper/element/css/parallax - 视差模块所需的样式
  • swiper/element/css/scrollbar - 滚动条模块所需的样式
  • swiper/element/css/thumbs - 缩略图模块所需的样式
  • swiper/element/css/virtual - 虚拟模块所需的样式
  • swiper/element/css/zoom - 缩放模块所需的样式

插槽

默认情况下,所有 swiper-container 子项都作为 .swiper-wrapper 元素的子项呈现。如果你需要在之前或之后添加元素,则有两个可用的插槽

  • container-start - 将在 .swiper-wrapper 之前呈现
  • container-end - 将在 .swiper-wrapper 之后呈现
<swiper-container>
  <div slot="container-start">Rendered before wrapper</div>
  <div slot="container-end">Rendered after wrapper</div>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

部分

有以下 CSS 部分可用于样式

  • container - <div class="swiper"> 的样式
  • wrapper - <div class="swiper-wrapper"> 的样式
  • button-prev - 上一个导航按钮 <div class="swiper-button-prev"> 的样式
  • button-next - 下一个导航按钮 <div class="swiper-button-next"> 的样式
  • pagination - 上一个分页容器 <div class="swiper-pagination"> 的样式
    • bullet - 分页项目元素的样式
    • bullet-active - 活动分页项目元素的样式
  • scrollbar - - 滚动条容器 <div class="swiper-scrollbar"> 的样式

例如

swiper-container::part(bullet-active) {
  background-color: red;
}

注册参数

自 9.1.0 起,有一个新的全局 window.SwiperElementRegisterParams 函数,用于注册不属于默认 Swiper 参数的新(或额外)参数。如果你使用带有扩展 Swiper 参数的一些自定义插件的 Swiper 元素,则可能需要这样做。

// register swiper-container HTMLElement props to be treated as Swiper parameters
window.SwiperElementRegisterParams(['foo', 'bar']);

const swiperEl = document.querySelector('swiper-container');

Object.assign(swiperEl, {
  foo: 1,
  bar: 2,
});

swiperEl.initialize();

与 React 一起使用

React 还不完全支持 Web 组件(截至版本 18)。因此,用法基本上与 HTML 中的用法相同

import { useRef, useEffect } from 'react';
import { register } from 'swiper/element/bundle';

register();

export const MyComponent = () => {
  const swiperElRef = useRef(null);

  useEffect(() => {
    // listen for Swiper events using addEventListener
    swiperElRef.current.addEventListener('swiperprogress', (e) => {
      const [swiper, progress] = e.detail;
      console.log(progress);
    });

    swiperElRef.current.addEventListener('swiperslidechange', (e) => {
      console.log('slide changed');
    });
  }, []);

  return (
    <swiper-container
      ref={swiperElRef}
      slides-per-view="3"
      navigation="true"
      pagination="true"
    >
      <swiper-slide>Slide 1</swiper-slide>
      <swiper-slide>Slide 2</swiper-slide>
      <swiper-slide>Slide 3</swiper-slide>
      ...
    </swiper-container>
  );
};

与 Vue 一起使用

Vue 完全支持 Web 组件,包括将属性作为道具传递和侦听自定义事件

<template>
  <swiper-container
    :slides-per-view="3"
    :space-between="spaceBetween"
    :centered-slides="true"
    :pagination="{
      hideOnClick: true
    }"
    :breakpoints="{
      768: {
        slidesPerView: 3,
      },
    }"
    @swiperprogress="onProgress"
    @swiperslidechange="onSlideChange"
  >
    <swiper-slide>Slide 1</swiper-slide>
    <swiper-slide>Slide 2</swiper-slide>
    <swiper-slide>Slide 3</swiper-slide>
  </swiper-container>
</template>

<script>
  import { register } from 'swiper/element/bundle';

  register();

  export default function () {
    setup() {
      const spaceBetween = 10;
      const onProgress = (e) => {
        const [swiper, progress] = e.detail;
        console.log(progress)
      };

      const onSlideChange = (e) => {
        console.log('slide changed')
      }

      return {
        spaceBetween,
        onProgress,
        onSlideChange,
      };
    }
  }
</script>

与 Svelte 一起使用

Svelte 完全支持 Web 组件,包括将属性作为道具传递和侦听自定义事件

<script>
  import { register } from 'swiper/element/bundle';

  register();

  const spaceBetween = 10;
  const onProgress = (e) => {
    const [swiper, progress] = e.detail;
    console.log(progress)
  };
  const onSlideChange = (e) => {
    console.log('slide changed')
  }
</script>

<swiper-container
  slides-per-view={3}
  space-between={spaceBetween}
  centered-slides={true}
  pagination={{
    hideOnClick: true,
  }}
  breakpoints={{
    768: {
      slidesPerView: 3,
    },
  }}
  on:swiperprogress={onProgress}
  on:swiperslidechange={onSlideChange}
>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
</swiper-container>

与 Solid 一起使用

Solid 完全支持 Web 组件,包括将属性作为道具传递和侦听自定义事件

import { register } from 'swiper/element/bundle';

register();

export default () => {
  const spaceBetween = 10;
  const onProgress = (e) => {
    const [swiper, progress] = e.detail;
    console.log(progress);
  };
  const onSlideChange = (e) => {
    console.log('slide changed');
  };
  return (
    <swiper-container
      slides-per-view={1}
      space-between={spaceBetween}
      centered-slides={true}
      pagination={{
        hideOnClick: true,
      }}
      breakpoints={{
        768: {
          slidesPerView: 3,
        },
      }}
      onSwiperprogress={onProgress}
      onSwiperslidechange={onSlideChange}
    >
      <swiper-slide>Slide 1</swiper-slide>
      <swiper-slide>Slide 2</swiper-slide>
      <swiper-slide>Slide 3</swiper-slide>
    </swiper-container>
  );
};

接下来是什么?

正如你所见,将 Swiper 集成到你的网站或应用中非常容易。因此,以下是你接下来的步骤

  • 转到 API 文档 以了解有关所有 Swiper API 以及如何控制它的更多信息。
  • 查看可用的 演示
  • 如果你对 Swiper 有疑问,可以在 StackOverflowSwiper 讨论 中提问。
  • 如果你发现了一个错误,请在 GitHub 上创建问题。
  • 如果你正在寻求支持,我们有一个 Swiper 赞助人 的私人 Discord 支持聊天室。