在nuxt2中使用swiper的坑
手中的vue2项目因为说后期要做SEO ,所以从CSR 转为SSR ,在进行迁移的过程中,发现首页的轮播图组件Swiper 一直报错,所以记录下来
备注:vue-awesome-swiper版本号是3.1.3
Window is not defined
报错原因是因为swiper 组件代码环境是客户端,但是他跑在了服务端脚本中所以会报错
解决方法有两种,第一种就是使用
arduino
if (process-client) {
// 需要跑在客户端的代码
}
还可以用<no-ssr></no-ssr>
标签包裹
xml
<no-ssr>
<swiper />
</no-ssr>
第三种就是通过nuxt.config.js
进行引入配置
- 先在根目录的plugin文件夹创建
vue-swiper.js
javascript
// vue-swiper.js
import Vue from 'vue'
if (process.browser) {
const VueAwesomeSwiper = require("vue-awesome-swiper/dist/ssr");
Vue.use(VueAwesomeSwiper);
}
- 之后再
nuxt.config.js
中进行引入配置
arduino
// nuxt.config.js
export default {
plugin: [
'@/plugins/vue-swiper'
],
css: [
'swiper/dist/css/swiper.css'
]
}
注意:在nuxt中使用swiper不能以组件形式引入了,需要使用div配合class的方式引入
引用自vue-awesome-swiper官方
github.com/surmon-chin...
xml
<template>
<div v-swiper:mySwiper="swiperOption" @someSwiperEvent="callback">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="banner in banners">
<img :src="banner">
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</template>
<script>
export default {
data () {
return {
banners: [ '/1.jpg', '/2.jpg', '/3.jpg' ],
swiperOption: {
pagination: {
el: '.swiper-pagination'
},
// some swiper options...
}
}
},
mounted() {
setTimeout(() => {
this.banners.push('/4.jpg')
console.log('banners update')
}, 3000)
console.log(
'This is current swiper instance object', this.mySwiper,
'It will slideTo banners 3')
this.mySwiper.slideTo(3, 1000, false)
}
}
</script>
发现swiper中的配置项失效
发现轮播图不会自动播放,并且样式不对,应该是配置项失效了
但是当代码中更改后并保存,页面中效果会恢复正常,刷新后再次失效,后端返回的图片也可以正常显示
测试后发现如果用本地图片不会出现问题,应该是获取到后端图片后swiper没有重新进行初始化
使用配置项中的observe
相关属性配置后发现问题依然无法解决
所以采用watch配合v-if让组件重新加载
xml
<template>
<div v-swiper:mySwiper="swiperOption" v-if="isShow">
<div class="swiper-wrapper banner">
<div class="swiper-slide item" v-for="(item,i) in banners" :key="i">
<img class="swiper-img" :src="item.imgUrl" :class="{active:currentIndex === i}" @click="itemClick(i)">
</div>
</div>
</div>
</template>
<script>
export default {
props: {
banners: {
type: Array,
default: () => []
}
},
data() {
return {
isShow: false
}
},
watch() {
// 后端传值过来后banners的值发生变化,触发v-if
banners() {
this.isShow = true
}
}
}
</script>