1

商城项目使用nuxt架构

使用轮播图,选择了时下最热门的vue-awesome-swiper作为基础组件。但是使用过程中遇到的坑,真的很难受

nuxt的版本是2.14.6

在vuecli中构建使用vue-awesome-swiper组件没有任何问题,
但是加上ssr就一直会报错,原生组件的切换上一个下一个的按钮不显示,即便是显示了点击也不会生效,后面排查也不知道是不是电脑硬件的问题,我们使用要求切换按钮需要自定义(包括按钮行为)

这儿直接上我们目前的组件代码

<template>
    <div v-swiper:mySwiper="sweiperConfig.options" :style="{ width: `${sweiperConfig.width}px`, height: `${sweiperConfig.height}px` }">
        <div class="swiper-wrapper">
            <slot name="swiperbody"></slot>
        </div>
        <a-icon
            v-if="iconConfig.prevShow"
            class="swiper-left-btn"
            :style="{ ...iconConfig.iconCss }"
            type="left"
            :disabled="iconConfig.prevDisabled"
            @click="prev"
        />
        <a-icon
            v-if="iconConfig.nextShow"
            class="swiper-right-btn"
            :style="{ ...iconConfig.iconCss }"
            type="right"
            :disabled="iconConfig.nextDisabled"
            @click="next"
        />
    </div>
</template>

<script>
export default {
    props: {
        // sweiper配置,options是sweiper官方配置,具体请查看官方文档
        sweiperConfig: {
            type: Object,
            default: () => {
                return {
                    options: {
                        type: Object,
                        default: () => {}
                    },
                    width: {
                        type: Number,
                        default: 300
                    },
                    height: {
                        type: Number,
                        default: 300
                    }
                }
            }
        },
        // icon配置,这是配置自定义的图标的样式
        iconConfig: {
            type: Object,
            default: () => {
                return {
                    prevShow: {
                        type: Boolean,
                        default: true
                    },
                    nextShow: {
                        type: Boolean,
                        default: true
                    },
                    prevDisabled: {
                        type: Boolean,
                        default: false
                    },
                    nextDisabled: {
                        type: Boolean,
                        default: false
                    },
                    iconCss: {
                        type: Object,
                        default: () => {
                            return {
                                'font-size': '30px',
                                padding: '10px',
                                top: '50%'
                            }
                        }
                    }
                }
            }
        }
    },
    mounted() {
        // 回传mySwiper实例,方便父组件使用该实例进行操作(调用方法或者事件)
        // 在父组件中对应的$emit方法定义到method中就能直接获取该实例,具体使用参考下文代码块中
        this.$emit('getSwiperObj', this.mySwiper)
    },
    methods: {
        prev() {
            this.mySwiper.slidePrev() //内置方法,往上翻一页
            // 当前的页码
            this.$emit('prevClick', this.mySwiper.realIndex + 1)
        },
        next() {
            this.mySwiper.slideNext() //内置方法,往下翻一页
            // 当前的页码
            this.$emit('nextClick', this.mySwiper.realIndex + 1)
        }
    }
}
</script>

<style lang="scss" scoped>
@mixin swiper-btn {
    background-color: #fff;
    border-radius: 50%;
    position: absolute;
    z-index: 2;
}
.swiper-wrapper {
    .swiper-slide {
        &:hover {
            cursor: pointer;
        }
    }
    .img-wrapper img {
        margin: auto;
        width: 200px;
        height: 100px;
        background-image: linear-gradient(gray 100%, transparent 0);
    }
}
.swiper-left-btn {
    @include swiper-btn;
    left: 5px;
}
.swiper-right-btn {
    @include swiper-btn;
    right: 5px;
}
.swiper-left-btn,
.swiper-right-btn {
    &:hover {
        background-color: #ccc;
    }
}
</style>

需要特别注意的是,<slot name="swiperbody"></slot>,这里的slot,在页面内使用要用v-slot的方式,这儿v-slot简写,不清楚的去vue官网查看

class="sweiper-slide"这个属性不能丢掉,这是sweiper源码获取子元素用的

<VueSwiper
    :sweiper-config="sweiperConfig"
    :icon-config="iconConfig"
    @getSwiperObj="getSwiperObj"
    @prevClick="prevClick"
    @nextClick="nextClick"
>
    <template #swiperbody>
       <img v-for="(img, index) in imgs" :key="index" :src="img.url" class="swiper-slide" />
    </template>
</VueSwiper>

参考文章: nuxt使用vue-awesome-sweiper采坑


万年打野易大师
1.5k 声望1.1k 粉丝