You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt3中i18n切换语言时Swiper组件报错问题求助

Nuxt i18n切换语言时Swiper报错:Cannot read properties of undefined (reading 'removeEventListener')

这个报错是因为语言切换时,i18n触发组件重新渲染,原Swiper实例在销毁过程中被提前清理,但残留的事件监听仍尝试调用实例方法,导致找不到removeEventListener的调用对象。

以下是两种可行的解决方法:

方案1:给Swiper绑定locale相关的key(最简单)

直接给<Swiper>组件添加和当前语言绑定的key,让Vue在语言切换时完全销毁旧组件并创建新实例,从根源避免旧实例的残留问题:

<template>
  <Swiper
    :key="locale" <!-- 添加这一行 -->
    :modules="[SwiperAutoplay, SwiperGrid]"
    :slides-per-view="1"
    :space-between="30"
    loop
    effect="slide"
    :breakpoints="{
      1200: { slidesPerView: 3 }, 
      768: { slidesPerView: 2 },
      320: { slidesPerView: 1 } 
    }"
    :autoplay="{
      delay: 4000,
      disableOnInteraction: false,
    }"
  >
    <!-- 注意:把key从index换成slide的唯一标识,比如slide.id,避免组件复用异常 -->
    <SwiperSlide v-for="slide in carousalData.carousel_items" :key="slide.id">
      <HomeCarouselCard :slide="slide"/>
    </SwiperSlide>
  </Swiper>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
// ...其他导入和业务逻辑
</script>

方案2:手动控制Swiper实例的销毁与重建

如果方案1不满足需求,可通过ref获取Swiper实例,在语言切换前手动销毁旧实例:

<template>
  <Swiper
    ref="swiperRef"
    :modules="[SwiperAutoplay, SwiperGrid]"
    :slides-per-view="1"
    :space-between="30"
    loop
    effect="slide"
    :breakpoints="{
      1200: { slidesPerView: 3 }, 
      768: { slidesPerView: 2 },
      320: { slidesPerView: 1 } 
    }"
    :autoplay="{
      delay: 4000,
      disableOnInteraction: false,
    }"
  >
    <SwiperSlide v-for="slide in carousalData.carousel_items" :key="slide.id">
      <HomeCarouselCard :slide="slide"/>
    </SwiperSlide>
  </Swiper>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
import { useI18n } from 'vue-i18n'
import { Swiper, SwiperSlide } from 'swiper/vue'
import SwiperAutoplay from 'swiper/modules/autoplay'
import SwiperGrid from 'swiper/modules/grid'

const swiperRef = ref(null)
const { locale } = useI18n()
let swiperInstance = null

onMounted(() => {
  swiperInstance = swiperRef.value?.swiper
})

// 监听语言切换,提前销毁旧实例
watch(locale, async () => {
  if (swiperInstance) {
    // 销毁实例并清除所有事件监听和关联元素
    await swiperInstance.destroy(true, true)
    swiperInstance = null
  }
})

// 组件卸载时销毁实例,避免内存泄漏
onBeforeUnmount(() => {
  if (swiperInstance) {
    swiperInstance.destroy(true, true)
  }
})
</script>

额外注意点

  • 不要用index作为v-for的key,改用每个slide的唯一标识(比如slide.id),确保语言切换后数据更新时,SwiperSlide能正确重新渲染,避免组件复用导致的异常。
  • 如果你的carousalData是随语言切换动态加载的,记得监听carousalData的变化,必要时重新初始化Swiper。

内容的提问来源于stack exchange,提问作者hizbul25

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:17:25