【踩坑实录】nuxt项目使用轮播图组件vue-awesome-swiper

2,657 阅读2分钟

nuxt项目中需要使用轮播图组件vue-awesome-swiper,在网上找了一堆文章,照着做还是免不了踩坑,这里记录一下。

step 1 安装swiper

npm install swiper vue-awesome-swiper --save 我安装后的版本如下

"nuxt": "^2.15.3",
"swiper": "^6.7.0",
"vue-awesome-swiper": "^4.1.1"

step 2 注册swiper

方法1 Global Registration

首先,plugins目录下新增swiper.js:

import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
import 'swiper/swiper.min.css'
Vue.use(VueAwesomeSwiper)

注意:官网上写的是import 'swiper/css/swiper.css',但是我这样写的话会报“module not found”,翻了一下组件的安装目录,发现应该是'swiper/swiper.min.css'或者'swiper/swiper.css'

然后,在nuxt.config.js中配置:

plugins: [
    '~/plugins/element-ui',
    { src: "~/plugins/swiper.js", ssr: false }
],

这里有一个很奇怪的点,我一开始写的是~/plugins/swiper,发现nuxt不会加载,要写~/plugins/swiper.js才会加载,后缀名不能省略,不造为啥!

方法2 Local Registration

若是按标签模式使用swiper(step 3-方式1

则在组件中添加如下代码:

import { Swiper, SwiperSlide } from 'vue-awesome-swiper'
import 'swiper/swiper.css'
 
export default {
  components: {
    Swiper,
    SwiperSlide
  }
}

注意:这里加载进来的的SwiperSwiperSlide的首字母要大写,我一开始写的小写,在按照step 3-方式1使用的时候会报错:

[Vue warn]: Unknown custom element: <swiper> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

若是按指令模式使用swiper(step 3-方式2

则在组件中添加如下代码:

import { directive } from 'vue-awesome-swiper'
import 'swiper/swiper.css'
 
export default {
  directives: {
    swiper: directive
  }
}

注意:若是没有以上的注册代码,在按照step 3-方式2使用的时候会报错:

[Vue warn]: Failed to resolve directive: swiper

step 3 使用swiper

方式1 使用<swiper>标签模式

<client-only>
    <swiper :options="swiperOption">
        <div class="swiper-wrapper">
          <swiper-slide v-for="(item, ind) in prodData.indexImages" :key="'indexImg' + ind">
            <img :src="item">
          </swiper-slide>
        </div>
    </swiper>
</client-only>

注意

  • <client-only>要有,不然会报错:

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

方式2 也可以使用directive模式:

<client-only>
<div v-swiper:swiper="swiperOption">
    <div class="swiper-wrapper">
      <div v-for="(item, ind) in prodData.indexImages" :key="'indexImg' + ind" class="swiper-slide">
        <img :src="item">
      </div>
    </div>
</div>
</client-only>

官方推荐在ssr中使用的是directive模式。vue-awesome-swiper具有一个内置directive的客户端渲染Swiper。directive最大的好处是HTML仍可以在服务器端渲染网页并输出,以便搜索引擎可以正确捕获目标内容。

别忘了还有:

<script>
export default {
    data () {
        return {
            swiperOption: {
                direction: 'vertical',
                slidesPerView: 4,
                spaceBetween: 8,
                navigation: {
                  nextEl: '.button-next',
                  prevEl: '.button-prev'
                }
            }
        }
    }
}

navigation not working

swiper显示没问题了,手动拖动也是可以滚动的,可是点击navigation没反应(当然我html中是有<div class="button-prev"><div class="button-next">的,只是我上面的代码没写而已),仔细检查代码都没啥问题,后来把swiper换回5的版本,就OK了(注意:换回5后,plugins/swiper.js中,import css的路径要相应做修改:import 'swiper/css/swiper.min.css')。参考文章 image.png