vue3中onMounted与onActivated中代码执行顺序的问题?

onMounted第一次打开执行,
onActivated跳转到这个页面执行,
有一种情况,项目第一个打开,从别到页面跳转到这个页面时onMounted和onActivated会都执行,这时就会有一个问题,onMounted中的可能耗时长的会在onActivated执行时才执行完成,这时就出现了问题。这个问题怎么解决?

onActivated(async ()=>{
 
  
})
onMounted(async ()=>{
  console.log('onMounted开始')
  await getPayType()
  await defaultDate()
  await getData()
  console.log("onMounted结束")
})
阅读 8.6k
3 个回答
根据评论区。

那你就把 onMounted 里的逻辑抽出来变成一个 Promise 就好了。

let p;

onMounted(() => {
  p = new Promise(async (resolve, reject) => {
    try {
      await getPayType();
      await defaultDate();
      await getData();
      resolve();
    } catch (err) {
      reject(err);
    }
  });
})

onActivated(() => {
  p.then(async () => {
    // do something after `p` is completed
  });
})

P.S. 要是觉得这么写不够优雅那就上 RxJS 的 Observable 解耦。本质是一样的。

let isMountedCompleted = false;

onMounted(async () => {
  console.log('onMounted开始')
  await getPayType()
  await defaultDate()
  await getData()
  console.log("onMounted结束")
  isMountedCompleted = true;
})

onActivated(async () => {
  if (!isMountedCompleted) {
    await new Promise(resolve => {
      const checkInterval = setInterval(() => {
        if (isMountedCompleted) {
          clearInterval(checkInterval);
          resolve();
        }
      }, 100);
    });
  }
})

可以改用 异步watch 来代替 onActivated 实现你的需求,示例如下:

import type { WatchStopHandle } from "vue";
import { onBeforeUnmount, onMounted, shallowRef, watch } from "vue";

import { useRoute } from "vue-router";

const route = useRoute();

const unwatch = shallowRef<WatchStopHandle | null>(null);

function sleep(timeout: number) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(undefined);
    }, timeout);
  });
}

onMounted(async () => {
  // 执行onMounted的异步方法
  await sleep(2000);

  // 执行完成后开始监听route.path的变化
  unwatch.value = watch(() => route.path, async (path) => {
    // 注意先判断path
    if (path !== "当前页面的path") {
      return;
    }

    // 执行onActivated的异步方法
    await sleep(2000);
  }, { immediate: true });
});

// 手动停止异步watch
onBeforeUnmount(() => {
  unwatch.value?.();
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题