Skip to content

vue3 h5端,当上个页面有for循环的标签并给标签加上ref引用时,在某些情况下,会导致下个页面离开时不会被正常销毁(附最小复现demo) #5390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1SZX1 opened this issue Apr 15, 2025 · 5 comments

Comments

@1SZX1
Copy link

1SZX1 commented Apr 15, 2025

发行方式

H5

具体平台

edge135.0.3179.73

开发环境

Windows

项目创建方式

CLI命令行

依赖版本

3.0.0-4050720250324001

问题描述

ue3 h5端,当上个页面有for循环的标签并给标签加上ref引用时,在某些情况下,会导致下个页面离开时不会被正常销毁

重现步骤

  1. 新建一个页面a,添加用for循环遍历的view标签,为view标签添加ref属性并在setup中定义
  2. 调用uni.redirectTo跳转到页面b
  3. 页面b调用uni.redirectTo跳转回页面a

期望行为

页面b被销毁,onUnmounted生命周期被调用

实际行为

页面b只是失活并调用了onDeactivated生命周期,并未被销毁,onUnmounted生命周期未被调用

截图或录屏

复现demo

@1SZX1
Copy link
Author

1SZX1 commented Apr 15, 2025

<template>
  <view>
    页面a
    <!-- 引起bug的代码,以下条件缺一不可
     1:页面有v-for生成的标签
     2:标签本身或者子组件有ref属性并在setup中已定义
     3:两个页面通过uni.redirectTo互相跳转
      -->
    <template v-if="isShowList">
      <!-- <view v-for="item in 2" :key="item" ref="itemRef">
        {{ item }}这样也能复现
      </view> -->
      <view v-for="item in 2" :key="item">
        <view ref="itemRef">{{ item }}</view>
      </view>
    </template>
    <switch :checked="isShowList" @change="isShowList = $event.detail.value"></switch>列表开关,关闭后没有bug
    
    <button @click="redirectSecond" type="warn">redirectTo二级页面</button>
    通过uni.redirectTo跳转到页面b,页面b再uni.redirectTo回页面a,会导致页面b没有正常销毁
    <button @click="toSecond" type="primary">navigateTo二级页面</button>
    通过navigateTo跳转到页面b,页面b再正常返回或重定向,页面b会正常销毁
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const isShowList = ref(true)

const itemRef = ref()

function redirectSecond() {
  uni.redirectTo({ url: '/pages/second/second' })
}
function toSecond() {
  uni.navigateTo({ url: '/pages/second/second' })
}
</script>

<style></style>
<template>
  <view>
    页面b
    <button @click="redirectTo">redirectTo页面a</button>
    <button @click="navigateBack">navigateBack页面a</button>
  </view>
</template>

<script setup lang="ts">
import { onDeactivated, onUnmounted } from 'vue'

function redirectTo() {
  uni.redirectTo({ url: '/pages/index/index' })
}
function navigateBack() {
  uni.navigateBack()
}
onUnmounted(() => {
  alert('页面卸载,已销毁')
})
onDeactivated(() => {
  alert('页面失活,没有销毁')
})
</script>

<style></style>

@chouchouji
Copy link
Contributor

这样试试呢

Image

<template>
  <view>
    页面a
    <!-- 引起bug的代码,以下条件缺一不可
     1:页面有for循环遍历的swiper-item子组件,有没有swiper父组件都无所谓
     2:swiper-item本身或者子组件有ref属性并在setup中已定义
     3:两个页面通过uni.redirectTo互相跳转
      -->
    <swiper>
      <swiper-item v-for="item in 2" :key="item">
        <view :ref="setItemRef">{{ item }}</view>
      </swiper-item>
    </swiper>

    <button @click="redirectSecond" type="warn">redirectTo二级页面</button>
    通过uni.redirectTo跳转到页面b,页面b再uni.redirectTo回页面a,会导致页面b没有正常销毁
    <button @click="toSecond" type="primary">navigateTo二级页面</button>
    通过navigateTo跳转到页面b,页面b再正常返回或重定向,页面b会正常销毁
  </view>
</template>

<script setup lang="ts">
import { ref } from "vue";

const itemRefs = ref([]);

// 使用函数 ref 来动态收集多个元素引用
const setItemRef = (el) => {
  if (el) {
    itemRefs.value.push(el);
  }
};

function redirectSecond() {
  uni.redirectTo({ url: "/pages/second/second" });
}
function toSecond() {
  uni.navigateTo({ url: "/pages/second/second" });
}
</script>

<style></style>

@1SZX1 1SZX1 changed the title vue3 h5端,当上个页面有swiper组件时,在某些情况下,会导致下个页面离开时不会被正常销毁(附最小复现demo) vue3 h5端,当上个页面有for循环的标签并给标签加上ref引用时,在某些情况下,会导致下个页面离开时不会被正常销毁(附最小复现demo) Apr 16, 2025
@1SZX1
Copy link
Author

1SZX1 commented Apr 16, 2025

这样试试呢

Image

<template>
  <view>
    页面a
    <!-- 引起bug的代码,以下条件缺一不可
     1:页面有for循环遍历的swiper-item子组件,有没有swiper父组件都无所谓
     2:swiper-item本身或者子组件有ref属性并在setup中已定义
     3:两个页面通过uni.redirectTo互相跳转
      -->
    <swiper>
      <swiper-item v-for="item in 2" :key="item">
        <view :ref="setItemRef">{{ item }}</view>
      </swiper-item>
    </swiper>

    <button @click="redirectSecond" type="warn">redirectTo二级页面</button>
    通过uni.redirectTo跳转到页面b,页面b再uni.redirectTo回页面a,会导致页面b没有正常销毁
    <button @click="toSecond" type="primary">navigateTo二级页面</button>
    通过navigateTo跳转到页面b,页面b再正常返回或重定向,页面b会正常销毁
  </view>
</template>

<script setup lang="ts">
import { ref } from "vue";

const itemRefs = ref([]);

// 使用函数 ref 来动态收集多个元素引用
const setItemRef = (el) => {
  if (el) {
    itemRefs.value.push(el);
  }
};

function redirectSecond() {
  uni.redirectTo({ url: "/pages/second/second" });
}
function toSecond() {
  uni.navigateTo({ url: "/pages/second/second" });
}
</script>

<style></style>

虽然麻烦了些,不过确实可以👍

@1SZX1
Copy link
Author

1SZX1 commented Apr 16, 2025

刚才又发现这个问题跟swiper无关,无论什么标签都会出现这个问题

@chouchouji
Copy link
Contributor

刚才又发现这个问题跟swiper无关,无论什么标签都会出现这个问题

是的,ref的使用出了问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants