如何在 Nuxt 3 应用程序中添加页面加载器

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

我正在使用 Nuxt 3 构建一个应用程序,我想添加一个页面加载器直到网站加载。

vue.js nuxt.js nuxtjs3
5个回答
8
投票

根据这篇文章。有一种简单但有限的解决方案和一种完全定制的解决方案。

内置
<NuxtLoadingIndicator>

<NuxtLoadingIndicator>
包含一个加载进度条,可以像这样使用

<template>
  <NuxtLayout>
    <NuxtLoadingIndicator />
    <NuxtPage />
  <NuxtLayout>
</template>

但它只有一个预定义的 UI,并且只能使用这几个属性进行自定义

  • 颜色:加载栏的颜色。
  • 高度:加载栏的高度,以像素为单位(默认为3)。
  • 持续时间:加载栏的持续时间,以毫秒为单位(默认为2000)。
  • Throttle: 限制显示和隐藏,以毫秒为单位(默认为200)。

可定制加载器

如果您需要自定义加载程序(例如带背景的全屏旋转器),则需要不同的方法。这种方法允许您创建任何加载程序并在需要时显示它。

<template>
  <div class="h-screen">
    <div v-if="loading" class="fixed left-0 top-0 h-0.5 w-full z-50 bg-green-500" />

    <NuxtLayout>
      <NuxtPage />
    </NuxtLayout>
  </div>
</template>

<script setup lang="ts">
  const nuxtApp = useNuxtApp();
  const loading = ref(false);
  nuxtApp.hook("page:start", () => {
    loading.value = true;
  });
  nuxtApp.hook("page:finish", () => {
    loading.value = false;
  });
</script>

Nuxt3 提供了应用程序运行时挂钩,其中包含针对

page:start
page:finish
事件的拦截器。要正确使用它们,您需要以这种方式使用这些钩子(在 app.vue 或您的自定义组件中):


1
投票

<NuxtLoadingIndicator>
组件在页面导航上显示进度条。” – 来自 Nuxt3 文档
<NuxtLoadingIndicator>

我认为这也是用于在开发设置中显示加载指示器的。


0
投票

我为 Nuxt3 制作了一个自定义解决方案,使用 pinia 进行状态管理和全局中间件,该解决方案的工作原理与 Nextjs-ProgressBar

商店/ui.js

import { defineStore } from "pinia";

const useUiStore = defineStore("uiStore", {
    state: () => {
        return {
            pageLoader: false,
        };
    },
    actions: {
        setPageLoader(value) {
            this.pageLoader = value

        },
    },
});

if (import.meta.hot) {
    import.meta.hot.accept(acceptHMRUpdate(useUiStore, import.meta.hot));
}

export default useUiStore;

中间件/ui.global.js

import useUiStore from "~~/stores/ui";

export default defineNuxtRouteMiddleware(async(to, from) => {
    useUiStore().setPageLoader(true)
})

组件/LoaderIndicator.vue

<script setup>
import useUiStore from '~~/stores/ui';

const nuxtApp = useNuxtApp();

nuxtApp.hook("page:finish", () => {
    if(useUiStore().$state.pageLoader == true){
        useUiStore().setPageLoader(false)
    }
});

</script>
<script>
export default {
    watch: {
    showLoader(newVal, oldVal) {
      if (newVal == true) {
        this.$refs.progressBar.style.opacity = '1';
        this.$refs.progressBar.style.transitionDuration = '1000ms';
        this.$refs.progressBar.style.width = '40%';
      } else if (newVal == false) {
        this.$refs.progressBar.style.transitionDuration = '1000ms';
        this.$refs.progressBar.style.width = '100%';
        setTimeout(() => {
          this.$refs.progressBar.style.opacity = '0';
          this.$refs.progressBar.style.transitionDuration = '0ms';
          this.$refs.progressBar.style.width = '0%';
        }, 1000);
      }
    },
  },
  computed: {
    showLoader() {
      return useUiStore().$state.pageLoader;
    }
  },
};
</script>
<template>
    <div ref="progressBar" class="fixed left-0 top-0 z-50 transition-all bg-orange h-[3px] LoadingBar shadow-[0_0_10px] shadow-orange " :style="{ width :'0%' }"></div>
</template>

应用程序.vue

<template>
    <NuxtLayout>
        <LoaderIndicator />
        <NuxtPage />
    </NuxtLayout>
</template>

请评论优化

谢谢你


0
投票

我没有使用

<NuxtLoadingIndicator>
,而是使用了全局中间件 +
page:finish
钩子,例如:

<template>
    <div v-show="show">
        Loading...
    </div>
</template>

<script setup>
    const nuxtApp = useNuxtApp();
    const show = ref(false);

    addRouteMiddleware('global-loader', () => {
        show.value = true
    }, {
        global: true
    })

    nuxtApp.hook('page:finish', () => { show.value = false; })
</script>

因此,在每次路线更改时,我们都会显示加载程序并在显示页面时隐藏它。

您可以将模板替换为您想要的模板,一些旋转器或其他东西。


0
投票

我认为这也有帮助,但它涉及 javascript。

<div id="loading">Loading...</div>

~/plugins/loading.ts

export default defineNuxtPlugin((nuxtApp) => {
    nuxtApp.hook('page:finish', () => {
        const loadingElement = document.querySelector('#loading')
        if (loadingElement) {
            loadingElement.remove()
        }
    })
})

一旦钩子触发,它将删除文档中的微调器。

© www.soinside.com 2019 - 2024. All rights reserved.