当前位置: 首页 > 知识库问答 >
问题:

javascript - vue3 组件实例未销毁?

越宣
2024-04-29
<script setup>import { useDocumentVisibility } from '@vueuse/core'import { timeFormat } from '@/utils/time.js'import { scrollToTop } from '@/utils/dom.js'const visibility = useDocumentVisibility()const searchQuery = reactive({  page: 1,  size: 14,  status: '',  account: '',  postId: ''})const searchQueryFormRef = ref(null)const state = reactive({  pageList: []})const totalPage = ref(0)let autoUpdateTimer = nullconst autoUpdateCheck = ref(false)let getListSignal = nullfunction clearAutoUpdate() {  if (autoUpdateTimer) {    clearTimeout(autoUpdateTimer)    autoUpdateTimer = null  }}function getList(goTop = false) {  // if (getListSignal) {  //   getListSignal.abort()  // }  // getListSignal = new AbortController()  window.aaa += 1  console.log('window.aaa', window.aaa)  api.queueList(toRaw(searchQuery), {    // signal: getListSignal.signal  }).then((res) => {    window.aaa -= 1    console.log(res.data.data[0])    state.pageList = res.data.data    totalPage.value = res.data.totalPage    console.log('autoUpdateCheck.value', autoUpdateCheck.value)    console.log('visibility.value', visibility.value)    if (autoUpdateCheck.value && visibility.value === 'visible') {      autoUpdateTimer = setTimeout(() => {        getList()      }, 1000)    }    goTop && scrollToTop()  })}watch(visibility, (current) => {  console.log('current', current)  console.log('autoUpdateCheck.value', autoUpdateCheck.value)  console.log('visibility.value', visibility.value)  if (current === 'visible') {    if (autoUpdateCheck.value) {      getList()    }  } else {    clearAutoUpdate()  }})function searchList() {  searchQuery.page = 1  getList(true)}function paginationChange(val) {  console.log(val)  searchQuery.page = val  getList(true)}function resetSearchForm() {  searchQueryFormRef.value.reset()  searchList()}searchList()function autoUpdateChange(e) {  console.log(e)  if (e) {    getList()  } else {    clearAutoUpdate()  }}onMounted(() => {  console.log('onMounted')})onActivated(() => {  console.log('onActivated')})onDeactivated(() => {  console.log('onDeactivated')})onBeforeUnmount(() => {  console.log('onBeforeUnmount')  clearAutoUpdate()})onUnmounted(() => {  clearAutoUpdate()  console.log('onUnmounted')})</script>

vue3
接口pending 的时候,切换路由,理论当前实例会被销毁,autoUpdate 变量 和 visible 变量都不存在了,但是打印出来仍然存在。导致离开页面了,定时器还在执行。

关键点在,路由已经切换了 if (autoUpdateCheck.value && visibility.value === 'visible') 这个条件依然成立,导致定时器执行

1.组件实例为什么没有销毁

生命周期都正常执行。
页面没有keep-alive

共有2个答案

上官鸿晖
2024-04-29
  • 你还在用的变量都不会销毁,即使只是console.log。
  • 定时器需要手动销毁,如果嫌麻烦,可以自定义一个hook,比如 useMyInterval
  • 即使定时器销毁了,但你的网络请求依然在执行,也只能手动abort请求或者组件销毁后判断以下,不执行请求回调里的操作
卫宁
2024-04-29

Vue 3 的组件实例在路由切换时确实应该被销毁,如果你遇到组件实例未销毁的问题,可能有几个原因:

  1. 路由配置问题
    确保你的路由配置中没有错误,尤其是没有错误地使用了 keep-alive 或者其他可能导致组件缓存的配置。
  2. 异步操作管理
    在 Vue 组件中,如果你有异步操作(如 API 调用、定时器、订阅事件等),你需要在组件卸载时正确地清理它们。在你的代码中,autoUpdateTimer 应该在组件卸载时清除,但你也要确保 getList 函数内部没有创建其他可能导致组件保持活动状态的异步操作。
  3. Vue 的响应式系统
    Vue 的响应式系统可能在你预期组件销毁之后仍然保持一些变量的活性。即使组件实例被销毁,Vue 的响应式系统仍然可能保留对变量的引用,直到没有任何活跃组件或实例引用它们。在你的例子中,autoUpdateCheckvisibility 可能是响应式引用,即使组件被销毁,它们也可能继续存在,直到没有其他活动组件引用它们。
  4. 控制台日志输出
    如果你在控制台看到变量仍然存在的日志输出,这可能是因为日志是在组件卸载之后异步执行的。即使组件实例已经被销毁,但异步回调(如 API 调用的 .then)可能仍然在队列中等待执行,因此当它们最终执行时,它们可能会输出到控制台。
  5. Vue 开发者工具
    如果你在使用 Vue Devtools,它可能会保留一些组件状态的信息,即使组件已经被销毁。这是为了帮助你调试,并不意味着组件实例实际上仍然存在。

为了解决这个问题,你可以尝试以下几个步骤:

  • 确保路由配置没有错误,并且没有使用 keep-alive
  • onBeforeUnmountonUnmounted 生命周期钩子中清理所有异步操作和定时器。
  • 检查组件中是否还有其他可能导致组件保持活动状态的异步操作或订阅事件。
  • 确保你没有在其他地方(如全局状态管理、事件总线等)保留对组件实例或其属性的引用。

最后,如果你确认组件实例没有被正确销毁,并且这导致了问题(如定时器继续运行),那么你可能需要进一步调查你的应用代码和 Vue 的使用方式,以找出为什么组件实例没有被销毁的原因。

 类似资料:
  • 如何在Children内部拿到父级的ref? 父级是不同的组件

  • 主要内容:全局组件实例,实例,实例,全局组件实例,局部组件实例,Prop,Prop 实例,Prop 实例组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树: 每个 Vue 应用都是通过用 createApp 函数创建的,传递给 createApp 的选项用于配置根组件。当我们挂载应用时,该组件被用作渲染的起点。 一个应用需要被挂载到一

  • 我试图删除一个对象(在这种情况下,和一个水果类的实例),当它与我的蛇的头相交。问题是,当它检测到一个水果对象时,似乎没有做任何事情。我不知道我是否没有正确实现删除函数,或者这可能与我如何将对象馈送到函数有关。 下面是处理游戏功能的main.py脚本的一部分: 以下是当头位于Fruit对象的相同位置时执行的函数: 如果我添加一个语句在下,它执行没有问题。问题是什么都不做。

  • 本文向大家介绍VUE实现自身整体组件销毁的示例代码,包括了VUE实现自身整体组件销毁的示例代码的使用技巧和注意事项,需要的朋友参考一下 V-IF实现组件自身销毁 前面说了一些自己怎么思考得来,如果时间急可直接看 最后~~~~ 通知提示组件案例分析 在编写一些简单的通知组件案例中,可能会这样去写 再看另一个Loading插件案例V-show template : javascript : 看完上一个

  • vue3 template组件不编译 代码是这样的,第二个template不会被编译 网页呈现是这样的,template没被编译掉?Hall组件倒是编译了

  • 在调用这个组件的地方 接收childer组件作为插槽,在parent中 获取不到默认插槽的属性b,不知道为什么