【问题标题】:How do I create a splash screen in VueJS?如何在 VueJS 中创建启动画面?
【发布时间】:2019-01-24 22:21:02
【问题描述】:

我正在尝试在 Vue JS 中创建一个启动屏幕(加载屏幕),它会在几秒钟后消失,显示我的默认视图。我尝试了几种方法,但都无法正常工作。最接近的是CodePen 上的这个示例,但理想情况下,该组件不会在 main.js 中,而是在它自己的组件中。尽管下面的代码不起作用。

我的 main.js 如下:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

Vue.config.productionTip = false;

// FILTERS
Vue.filter('snippet', function(value) {
    return value.slice(0,100);
});

Vue.component('loading-screen', {
  template: '<div id="loading">Loading...</div>'
})

new Vue({
  router,
  store,
  render: h => h(App),
  data: {
    isLoading: true
  },
  mounted () {
    setTimeout(() => {
      this.isLoading = false
    }, 3000)
  }
}).$mount("#app");

而我的App.vue如下

<template>
  <div id="app">

    <loading-screen v-if="isLoading"></loading-screen>

    <Top/>
    <router-view/>
    <PrimaryAppNav/>

  </div>
</template>


<script>

import Top from './components/Top.vue'
import PrimaryAppNav from './components/PrimaryAppNav.vue'


export default {
  name: 'app',
  components: {
    Top,
    PrimaryAppNav
  }
}
</script>

【问题讨论】:

  • 在 vue 之外做,这样它就可以在不等待 vue 加载的情况下加载,并且看起来会更好。然后当 vue 加载时,只需从 DOM 中删除元素。

标签: javascript vue.js vuejs2


【解决方案1】:

LoadingScreen.vue 组件可能如下所示:

<template>
  <div :class="{ loader: true, fadeout: !isLoading }">
    Loading ...
  </div>
</template>

<script>
export default {
  name: "LoadingScreen",
  props: ["isLoading"]
};
</script>

<style>
.loader {
  background-color: #63ab97;
  bottom: 0;
  color: white;
  display: block;
  font-size: 32px;
  left: 0;
  overflow: hidden;
  padding-top: 10vh;
  position: fixed;
  right: 0;
  text-align: center;
  top: 0;
}

.fadeout {
  animation: fadeout 2s forwards;
}

@keyframes fadeout {
  to {
    opacity: 0;
    visibility: hidden;
  }
}
</style>

请注意,加载程序需要知道加载是否完成才能淡出。您还需要在您的应用程序中检查它,因此它在仍需要准备数据时不会显示。否则,来自后台应用程序部分的信息可能会泄漏(例如,滚动条可能在 LoadingScreen 上可见)。所以App.vue 可以有这样的模板:

<template>
  <div id="app">
    <LoadingScreen :isLoading="isLoading" />
    <div v-if="!isLoading">
      ...your main content here...
    </div>
  </div>
</template>

如果您想让 LoadingScreen div 完全消失,您需要在 App.vue 本身中管理淡出动画的状态,使其更加复杂(我可能会为 LoadingScreen 使用两个道具: isLoadingfadeout,其中fadeout 是在淡出动画完成后立即在LoadingScreen 中调用的回调)。

我为你准备了一个codesandboxLoadingScreen里面的状态管理。

【讨论】:

    【解决方案2】:

    这是一个带有启动画面的工作 App.vue:

    <template>
        <div id="app">
            <v-app :light="!nav.dark" :dark="nav.dark">
                <transition name="slide-fade" mode="out-in">
                    <router-view></router-view>
                </transition>
            </v-app>
            <div v-if="loading" style="position:absolute; width: 100%; height:100%; top:0; left:0; z-index:10000; background-color:white">
                <div style="margin-left: auto; margin-right: auto">
                    Loading...
                </div>
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "app",
            data: () => ({
                loading: true
            }),
            mounted() {
                setTimeout(() => {
                    this.loading = false
                }, 3000)
            }
        }
    </script>
    

    请注意,有一个 z-index 技巧,并且挂载在 App 组件中。 您当然可以创建一个仅用于加载的组件,因此它将变为:

    App.vue

    <template>
        <div id="app">
            <v-app :light="!nav.dark" :dark="nav.dark">
                <transition name="slide-fade" mode="out-in">
                    <router-view></router-view>
                </transition>
            </v-app>
            <loader v-if="loading"/>
        </div>
    </template>
    
    <script>
        import Loader from "./Loader"
    
        export default {
            name: "app",
            data: () => ({
                loading: true
            }),
            mounted() {
                setTimeout(() => {
                    this.loading = false
                }, 3000)
            }
        }
    </script>
    

    Loader.vue

    <template>
        <div style="position:absolute; width: 100%; height:100%; top:0; left:0; z-index:10000; background-color:white">
            <div style="margin-left: auto; margin-right: auto">
                Loading...
            </div>
        </div>
    </template>
    
    <script>
        export default {
            name: "loader"
        }
    </script>
    

    在此之后,我强烈建议您为您的路由器组件 Top 和 PrimaryAppNav 使用动态组件。就像他们会在你的启动画面中加载一样。您将在我在此线程中的回答中轻松找到如何做到这一点(只有第 2 节与您相关):here

    【讨论】:

    • 感谢您的回答。但是我收到错误找不到此相关模块:n ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache -loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue
    • 您的示例无法正常工作。不清楚您是如何获得“v-app”组件的(它是 vuetify 项目示例吗?)。示例中的“导航”对象也未定义。
    猜你喜欢
    • 2012-02-23
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    相关资源
    最近更新 更多