uni-app v-if销毁子组件后 组件内的onReachBottom设置的监听依然存在

发布于 1周前 作者 ionicwang 来自 Uni-App

uni-app v-if销毁子组件后 组件内的onReachBottom设置的监听依然存在

bug描述:

需求:一个页面中有3个列表 内容各不相同
问题:3个子组件都设置了onReachBottom 3个组件做v-if切换的时候 无法取消监听 有什么合适的解决办法?

信息类型 信息内容
产品分类 uniapp/小程序/微信
项目创建方式 CLI
1 回复

uni-app 中,使用 v-if 指令动态销毁和重建组件时,确实可能会遇到组件内的事件监听器(如 onReachBottom)未正确移除的问题。这通常是因为在组件销毁时,相关的事件监听器没有被显式解绑。为了解决这个问题,我们可以在组件销毁时手动移除这些监听器。

以下是一个示例代码,展示了如何在 uni-app 中正确处理 v-if 条件下的组件销毁和事件监听器解绑:

父组件

<template>
  <view>
    <button @click="toggleComponent">Toggle Component</button>
    <child-component v-if="showComponent" @scrolltolower="handleScrollToLower" ref="childComponent" />
  </view>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      showComponent: true
    };
  },
  methods: {
    toggleComponent() {
      this.showComponent = !this.showComponent;
      if (!this.showComponent) {
        this.$refs.childComponent.removeScrollListener();
      }
    },
    handleScrollToLower() {
      console.log('Reached bottom!');
    }
  }
};
</script>

子组件 (ChildComponent.vue)

<template>
  <scroll-view scroll-y="true" @scrolltolower="onReachBottom">
    <!-- Your content here -->
  </scroll-view>
</template>

<script>
export default {
  methods: {
    onReachBottom() {
      this.$emit('scrolltolower');
    },
    removeScrollListener() {
      // In uni-app, scrolltolower is a native event and there's no direct way to remove it,
      // but we can define this method to ensure consumers know they should call it when needed.
      // In practice, you might need to manage custom listeners this way.
      console.log('Scroll listener removed (or attempted to be removed)');
      // If you had custom listeners, you would remove them here using `this.$off`.
    }
  },
  beforeDestroy() {
    // Automatically attempt to remove listeners when the component is destroyed
    // (though in this case scrolltolower is native and doesn't need explicit removal)
    this.removeScrollListener();
  }
};
</script>

注意:在 uni-app 中,@scrolltolower 是一个原生事件,通常不需要(也无法)手动移除。上述代码中的 removeScrollListener 方法主要是为了展示如何在组件销毁时执行一些清理操作。对于原生事件,uni-app 框架会在组件销毁时自动处理。

如果你使用的是自定义事件或第三方库的事件监听,确保在组件销毁前使用 this.$off 方法解绑这些事件监听器。

回到顶部