vue中用vue-awesome-swiper插件 移动端怎么实现缩放?

根据vue-awesome-swiper官网例子写的一个可以缩放的dome 轮播图,可以正常轮播,

     vue2 
      "swiper": "^6.8.4",
     "vue-awesome-swiper": "^4.1.1",

import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/swiper-bundle.css'; // 引入 Swiper 样式

引用是正确的

现在有个问题
页面有多张图片,当我点击某张图片时能获取到其下标initialIndex,我预期是点击某张图片弹层中显示某张图片,

swiperOption: {
    initialSlide: this.initialIndex,
},

这样写也获取不到,第一次用这个插件 希望得到指点

<template>
    <div v-if="showMaskLayout" class="image-overlay" @click="closeViewer">
        <swiper ref="mySwiper" :options="swiperOption" class="swiper">
            <swiper-slide v-for="(image, index) in urls" :key="index" class="my-slide-zoomed">
                <div class="swiper-zoom-container">
                    <img :src="image" />
                </div>
            </swiper-slide>
        </swiper>
    </div>
</template>

<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/swiper-bundle.css';

export default {
    data() {
        return {
            swiperOption: {
                width: window.innerWidth,
                zoom: true,
                initialSlide: this.initialIndex,
            },
            showMaskLayout: true,
            urls: [
                'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
                'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
                'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
                'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
                'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
                'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
                'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'
            ]
        };
    },
    props: {
        picList: {
            type: Array,
            default() {
                return [];
            },
        },
        currentImg: {
            type: [String, Array],
            default: () => '',
        },
        initialIndex: {
            type: Number,
            default: 0,
        },
        maskClosable: {
            type: Boolean,
            default: true,
        },
    },
    components: {
        Swiper,
        SwiperSlide,
    },
    mounted() {
        this.initSwiper(); // 在 mounted 中初始化 Swiper
    },
    created() {
        console.log('initialIndex', this.initialIndex)
    },
    methods: {
        closeViewer() {
            this.showMaskLayout = false;
            document.body.style.overflow = ''; // 恢复滚动条
        },
        initSwiper() {
            this.$nextTick(() => {
                if (this.$refs.mySwiper && this.$refs.mySwiper.swiper) {
                    this.$refs.mySwiper.swiper.update(); // 更新 Swiper 实例
                    this.$refs.mySwiper.swiper.slideTo(this.initialIndex, 0, false);
                } else {
                    // 如果 Swiper 实例未被创建,手动创建
                    this.swiperOption = {
                        ...this.swiperOption,
                        initialSlide: this.initialIndex
                    };
                }
            });
        }
    },
    watch: {
        showMaskLayout(newVal) {
            if (newVal) {
                this.initSwiper(); // 当弹层打开时初始化 Swiper
            }
        }
    },
};
</script>

<style scoped>
.image-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 1);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 9999;
}

.swiper {
    margin-left: auto;
    margin-right: auto;
    position: relative;
    overflow: hidden;
    overflow: clip;
    list-style: none;
    padding: 0;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;

    .swiper-wrapper {
        position: relative;
        width: 100%;
        height: 100%;
        z-index: 1;
        display: flex;
        transition-property: transform;
        transition-timing-function: var(--swiper-wrapper-transition-timing-function, initial);
        box-sizing: content-box;
    }

    .swiper-slide {
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
        flex-shrink: 0;
        height: 100%;
        position: relative;
        transition-property: transform;
        overflow: hidden;
        display: block;
        img {
            display: block;
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
        }
    }

    .swiper-zoom-container {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
    }
}
</style>

阅读 1.1k
avatarAI BotBETA

在您的代码中,虽然您已经启用了 Swiper 的 zoom 功能,但可能由于一些样式或配置的问题导致缩放功能没有按预期工作。这里有几个可能的原因和解决方案:

  1. 确保 Swiper 版本支持缩放功能
    首先,确认您使用的 Swiper 版本支持缩放功能。通常,swiper-bundle.cssswiper-bundle.js(或相应的 Vue 封装版本)包含所有功能,包括缩放。
  2. 检查 CSS 类和样式
    您的 CSS 中 .swiper-zoom-container 设置为 100% 的宽度和高度,这可能会限制图像的缩放。尝试给图像一个固定的最大宽度和高度,或者使用 CSS 的 max-widthmax-height 属性来确保图像可以在容器内缩放。

    修改 .swiper-slide img 的样式如下:

    .swiper-slide img {
        max-width: 100%;
        max-height: 100%;
        transition: transform 0.3s ease; /* 添加平滑的缩放过渡效果 */
        transform-origin: center center; /* 设置缩放的原点为中心 */
    }

    同时,确保 .swiper-zoom-container 不是必需的,因为 Swiper 的缩放功能通常会自动处理图像的缩放,不需要额外的容器。

  3. 检查 Swiper 初始化选项
    您的 Swiper 初始化选项看起来是正确的,但确保没有其他配置(如 loop: true)与缩放功能冲突。
  4. 浏览器兼容性
    检查您的代码在不同浏览器和设备上的表现。虽然 Swiper 在大多数现代浏览器上都能很好地工作,但某些旧版浏览器或移动设备可能不支持缩放功能。
  5. 控制台错误
    检查浏览器的开发者控制台是否有任何错误或警告,这可能会提供关于为什么缩放功能不起作用的线索。
  6. 更新 Swiper 和 vue-awesome-swiper
    如果可能,尝试更新 Swiper 和 vue-awesome-swiper 到最新版本,以确保您使用的是最新的功能和修复。

如果以上步骤都不能解决问题,您可能需要查看 vue-awesome-swiper 的官方文档或搜索类似的问题,看看是否有其他开发者遇到了类似的问题并找到了解决方案。

2 个回答

问题已解决,代码如下

<template>
    <div v-if="showMaskLayout" class="image-overlay" @click="closeViewer">
        <swiper ref="mySwiper" :options="swiperOption" class="swiper">
            <swiper-slide v-for="(image, index) in picList" :key="index" class="my-slide-zoomed">
                <div class="swiper-zoom-container">
                    <img :src="image" />
                </div>
            </swiper-slide>
        </swiper>
    </div>
</template>

<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/swiper-bundle.css';

export default {
    data() {
        return {
            swiperOption: {
                width: window.innerWidth,
                zoom: true,
                initialSlide: this.initialIndex,
            },
            showMaskLayout: true,
        };
    },
    props: {
        picList: {
            type: Array,
            default() {
                return [];
            },
        },
        currentImg: {
            type: [String, Array],
            default: () => '',
        },
        initialIndex: {
            type: Number,
            default: 0,
        },
        maskClosable: {
            type: Boolean,
            default: true,
        },
    },
    components: {
        Swiper,
        SwiperSlide,
    },
    mounted() {
        this.initSwiper(); // 在 mounted 中初始化 Swiper
    },
    created() {
        console.log('initialIndex', this.initialIndex)
        this.swiperOption.initialSlide = this.initialIndex
        this.$nextTick(() => {
            console.log('this.$refs.mySwiper', this.$refs.mySwiper)
            console.log('this.$refs.mySwiper.$swiper', this.$refs.mySwiper.$swiper)
            if (this.$refs.mySwiper && this.$refs.mySwiper.$swiper) {
                this.$refs.mySwiper.$swiper.slideTo(this.initialIndex, 0, false);
            }
        })
    },
    methods: {
        // 关闭弹层
        closeViewer() {
            this.showMaskLayout = false;
            document.body.style.overflow = ''; // 恢复滚动条
        },
        // 初始化 Swiper
        initSwiper() {
            this.$nextTick(() => {
                if (this.$refs.mySwiper && this.$refs.mySwiper.$swiper) {
                    console.log('this.initialIndex', this.initialIndex)
                    this.$refs.mySwiper.$swiper.update(); // 更新 Swiper 实例
                    this.$refs.mySwiper.$swiper.slideTo(this.initialIndex, 0, false);
                } else {
                    // 如果 Swiper 实例未被创建,手动创建
                    this.swiperOption = {
                        ...this.swiperOption,
                        initialSlide: this.initialIndex
                    };
                }
            });
        }
    },
    watch: {
        showMaskLayout(newVal) {
            if (newVal) {
                this.initSwiper(); // 当弹层打开时初始化 Swiper
            }
        }
    },
};
</script>

<style scoped>
.image-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 1);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 9999;
}

.swiper {
    margin-left: auto;
    margin-right: auto;
    position: relative;
    overflow: hidden;
    overflow: clip;
    list-style: none;
    padding: 0;
    z-index: 1;
    display: block;
    width: 100%;
    height: 100%;

    .swiper-wrapper {
        position: relative;
        width: 100%;
        height: 100%;
        z-index: 1;
        display: flex;
        transition-property: transform;
        transition-timing-function: var(--swiper-wrapper-transition-timing-function, initial);
        box-sizing: content-box;
    }

    .swiper-slide {
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
        flex-shrink: 0;
        height: 100%;
        position: relative;
        transition-property: transform;
        overflow: hidden;
        display: block;
        img {
            display: block;
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
        }
    }

    .swiper-zoom-container {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
    }
}
</style>

1.确保正确引入 Swiper 的 Zoom 模块: 你需要确保 Swiper 的 Zoom 模块被正确引入和使用。可以在 swiperOption 中明确指定模块。
2.检查 Swiper 版本兼容性: 确保 vue-awesome-swiper 和 Swiper 的版本兼容。你使用的 vue-awesome-swiper@4.1.1 适用于 Swiper 61。
3.样式调整: 确保 swiper-zoom-container 的样式没有问题,尤其是宽高设置。
以下是调整后的代码示例:

<template>
    <div v-if="showMaskLayout" class="image-overlay" @click.self="closeViewer">
        <swiper :options="swiperOption" class="swiper">
            <swiper-slide v-for="(image, index) in urls" :key="index">
                <div class="swiper-zoom-container">
                    <img :src="image" />
                </div>
            </swiper-slide>
        </swiper>
    </div>
</template>

<script>
    import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
    import 'swiper/swiper-bundle.css'; // 引入 Swiper 样式

    export default {
        data() {
            return {
                swiperOption: {
                    modules: [Swiper.Zoom], // 确保引入 Zoom 模块
                    zoom: {
                        maxRatio: 3, // 设置最大缩放比例
                    },
                    pagination: {
                        el: '.swiper-pagination',
                        clickable: true,
                    },
                    navigation: {
                        nextEl: '.swiper-button-next',
                        prevEl: '.swiper-button-prev'
                    },
                },
                showMaskLayout: true,
                urls: [
                    'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
                    'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
                    'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
                    'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
                    'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
                    'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
                    'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg'
                ]
            };
        },
        
        components: {
            Swiper,
            SwiperSlide,
        },
        mounted() {
            // Swiper 的 zoom 功能已经集成,不需要手动添加缩放逻辑
        },
        methods: {
            closeViewer() {
                if (this.maskClosable) {
                    this.showMaskLayout = false;
                    document.body.style.overflow = ''; // 恢复滚动条
                }
            },
        },
    };
</script>

<style scoped>
    .image-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, 1);
        display: flex;
        justify-content: center;
        align-items: center;
        z-index: 9999;
    }

    .swiper {
        width: 100%;
        height: 100%;

        .swiper-slide {
            display: flex;
            justify-content: center;
            align-items: center;
            text-align: center;

            img {
                width: 100%;
                height: auto;
            }
        }

        .swiper-zoom-container {
            width: 100%;
            height: 100%;
        }
    }
</style>

请确保你已经正确引入了 Swiper.Zoom 模块,并在 swiperOption 中配置了 zoom 选项。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏