Vue3/Vite Typescript:在 <Suspense #default>

问题描述 投票:0回答:1

我正在开发一个 Vue3/Vite Typescript 项目,使用

<Suspense>
在加载异步子组件时显示加载状态 #fallback 模板。这就像一个魅力。

但是我想在我的

<Suspense #default>
DOM 结构中拥有一个/多个元素的引用(例如,为一些漂亮的动画添加
IntersectionObserver
)。

我知道,当触发

onMounted()
钩子时,“目标”引用仍然未定义,因为当所有 static 内容准备就绪时(当异步组件仍在加载时;“加载器”引用返回
<div class="loader"> 时,就会发生这种情况) 
)。 Suspense 提供了
onResolve()
钩子,该钩子在加载 #default 模板中包含的所有异步组件后触发。 仍然“目标”引用未定义(“加载器”引用返回 null - 这没关系,因为它不再显示)。

测试:如果我删除

Introsection
(随着异步资源加载),
<Suspense>
会直接解析(在
onMounted()
之前),并且“目标”引用直接在
<section>
钩子中返回引用的
onMounted()
(在
onResolve()
钩子两个引用均未定义)。

我做错了什么?感谢任何有用的提示/解决方案。

我的代码(缩写):

import IntroSection from '@/components/IntroSection.vue'
import { useTemplateRef, onBeforeUpdate, onUpdated, onMounted, ref } from 'vue'

const target = ref<Element>() // or useTemplateRef('target')
const loader = ref<Element>()
const animate = ref<boolean>(true)

onMounted(() => {
  console.log('onMounted')
  console.log(target.value)
  console.log(loader.value)
})

onBeforeUpdate(() => {
  console.log('onBeforeUpdate')
})

onUpdated(() => {
  console.log('onUpdated')
})

function onPending() {
  console.log('onPending...')
}
function onResolve() {
  console.log('onResolve...')
  console.log(target.value)
  console.log(loader.value)
}

function onReject() {
  console.log('onReject')
}
</script>

<template>
  <Suspense :onPending="onPending" :onResolve="onResolve" :onReject="onReject">
    <template #default>
      <div>
        <!-- Spacer Section -->
        <section class="header_padding">
          <div class="container">
            <div class="row title"></div>
          </div>
        </section>
        <!-- End Spacer Section -->

        <!-- Intro Section with async asset loading -->
        <IntroSection>
          <div class="row title">
            <h1 class="header_headline_style_2">
              HEADLINE
            </h1>
            <p>
              <br />
              Some Text here
            </p>
            <br />
          </div>
        </IntroSection>
        <!-- End Intro Section -->

        <!-- Service Section -->
        <section ref="target">
          <div v-if="animate" class="nf-item spacing">
            <div class="box_module_1">
              <div class="box_module_2">
                <h2 class="h2_box">TITLE</h2>
                <p>TEXT</p>
              </div>
              <div class="box_module_2">
                <RouterLink to="/text" class="btn">
                  BUTTONTEXT
                </RouterLink>
              </div>
            </div>
          </div>
        </section>
        <!-- End Service Section -->
      </div>
    </template>

    <template #fallback>
      <!-- Preloader -->
      <section id="preloader">
        <div class="loader" id="loader" ref="loader">
          <div>Loading...</div>
          <div class="loader-img"></div>
        </div>
      </section>
      <!-- End Preloader -->
    </template>
  </Suspense>
</template>
typescript vuejs3 ref vue-script-setup vue-suspense
1个回答
0
投票

要在加载异步组件后访问

ref
组件中的
<Suspense>
,请使用
nextTick
挂钩中的
onResolve
函数来确保 DOM 已更新。确保您的
ref
已正确分配给预期元素。使用
console.log
中的
onResolve
进行调试可以帮助验证
ref
的时间和可用性。这种方法有助于管理组件的异步特性及其对 Vue 反应系统的影响。

import { nextTick } from 'vue';

function onResolve() {
  nextTick(() => {
    console.log(target.value); // Now, target should be defined
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.