nuxt(vue2)项目中使用swiper@8.x

635 阅读1分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

在 nuxt(vue2) 项目中使用 swiper @8.x 时,可能会导致页面打不开,怎么办呢?

最初按照官网的方式引入,然后new Swiper('.swiper', {/* ... */}),发现页面直接打不开。

在网上搜索相关文章几乎都是讲的swiper@5.x,而关于swiper@8.x的几乎是vue@3.x(有的文章讲到只能用到vue@3.x)。一度要放弃,但看到node_modeules下的swiper文件下有一些带和不带esm的js文件,于是猜测带esm适用于ES Module,不带的可能适用于普通的形式,于是决定自己尝试一下。经过一步步调试,终于发现采用按需导入 swiper 的方式可以解决,见第三部分。

1、template

<template>
  <div class="banner-swiper">
    <div class="swiper">
      <div class="swiper-wrapper">
        <div class="swiper-slide" style="background-color: red">1111</div>
        <div class="swiper-slide" style="background-color: blue">2222</div>
        <div class="swiper-slide" style="background-color: orange">3333</div>
        <div class="swiper-slide" style="background-color: purple">4444</div>
        <div class="swiper-slide" style="background-color: gold">5555</div>
      </div>
      <!-- 分页器 -->
      <div class="swiper-pagination"></div>

      <!-- 导航按钮 -->
      <div class="swiper-button-prev btn-left"></div>
      <div class="swiper-button-next btn-right"></div>
    </div>
  </div>
</template>

2、导入

// 一、一般的 vue 项目可以直接导入:
import Swiper from 'swiper/swiper-bundle.js'
import 'swiper/swiper-bundle.css'

// 二、在 nuxt 项目中按需导入 ⭐
import('swiper/swiper-bundle.js')

按需导入的原因可能是:Swiper在服务端运行时会导致错误,让它不在客户端导入就是了。

3、script

<script>
export default {
  name: 'CustomSwiper',
  async mounted() {
    // 二、客户端导入 ⭐
    if (process.browser) {
      // import() 返回的是Promise,因此需要通过await拿到导入的值
      const { default: Swiper } = await import('swiper/swiper-bundle.js')
      
      new Swiper('.swiper', {
        pagination: {
          el: '.swiper-pagination',
          clickable: true
        },
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev'
        },
        loop: true,
        autoplay: {
          delay: 3000,
          stopOnLastSlide: false,
          disableOnInteraction: false
        },
        effect: 'fade'
      })
    }
  }
}
</script>

<style>
.swiper-slide {
  height: 300px;
  color: #fff;
  line-height: 300px;
  text-align: center;
}
.swiper-button-next:after,
.swiper-button-prev:after {
  font-size: 12px;
}
.btn-left,
.btn-right {
  display: none;
  border: none;
  outline: 0;
  padding: 0;
  margin: 0;
  height: 36px;
  width: 36px;
  line-height: 36px;
  cursor: pointer;
  transition: 0.3s;
  border-radius: 50%;
  background-color: rgba(31, 45, 61, 0.11);
  color: #fff;
  position: absolute;
  top: 50%;
  z-index: 10;
  transform: translateY(-50%);
  text-align: center;
  font-size: 12px;
  &:hover {
    background-color: rgba(31, 45, 61, 0.231);
  }
}
.banner-swiper:hover .btn-left,
.banner-swiper:hover .btn-right {
  display: block;
}
.swiper-pagination-bullet {
  display: inline-block;
  border: none;
  outline: 0;
  padding: 0;
  background-color: #fff;
  cursor: pointer;
}
</style>

相关版本

nuxt: 2.14.6

vue: 2.6.14

swiper: 8.4.2

效果图:

动画5.gif

参考:Vue.js设计与实现-霍春阳(第18.5.3节:只在某一端引入模块)