【问题标题】:How to handle Vue component content before data has finished loading如何在数据加载完成之前处理 Vue 组件内容
【发布时间】:2020-12-28 19:18:44
【问题描述】:

我正在将一些来自 Prismic 的产品类别数据加载到我的 Nuxt 项目中,并且我正在寻找有关最佳实践的一些说明。具体来说,如何处理数据仍在抓取中,侧边栏没有内容可显示的状态。

现在,这是我的工作:

我有一个侧边栏组件 (Sidebar.vue):

<template>
    <div class="xl:flex-shrink-0 xl:w-64 border-r border-gray-200 pt-5 pb-4 bg-white overflow-y-auto ">
        <h3 class="text-xl font-bold text-gray-800">{{ navigation.heading }}</h3>
        <div class="mt-5 flex-grow flex flex-col">
            <nav class="flex-1 px-2 space-y-1 bg-white" aria-label="Sidebar">
            <div v-for="(category, index) in navigation.categories" :key="index">
                <SidebarItem v-if="!category.subcategories.length" :category="category"/>

                <SidebarSection v-else-if="category.subcategories.length" @click="toggleExpansion(index)" :category="category"/>
            </div>
            </nav>
        </div>
    </div>
</template>

<script lang="ts">
export default {
    data() {
        return {
            navigation: new Navigation('Categories')
        }
    },
    async mounted() {
        const that = this
        this.fetchCategories()
            .then(function() {
                that.navigation = that.$store.getters.navigation
            })
    },
    methods: {
        ...mapActions({ fetchCategories: 'fetchCategories' })
    }
}
</script>

如您所见,我有一个navigation 属性,它将包含填充侧边栏所需的所有数据。目前,我已经初始化了一个占位符实例 (new Navigation('Categories')),因为没有这个,Vue 报告 navigation 未定义。

感觉这不是解决此问题的理想方法。在不提供占位符实例的情况下,在加载数据之前处理此中间状态的最合适方法是什么?

【问题讨论】:

  • 我真的不觉得你在做什么有什么问题。您正在为 navigation 属性提供一个类型,该类型将在调试等时为您提供帮助,现在只需确保在使用它之前进行 null 检查并继续恕我直言。

标签: typescript vue.js vuex nuxtjs


【解决方案1】:

Nuxt 的fetch hook 在这里可能很有用。它公开了$fetchState(包括pendingerrortimestamp)以强制使用或在您的模板中使用。您的模板可以在渲染navigation 数据之前检查pending 标志:

<template>
    <div v-if="!$fetchState.pending" ?
        class="xl:flex-shrink-0 xl:w-64 border-r border-gray-200 pt-5 pb-4 bg-white overflow-y-auto">
        <h3 class="text-xl font-bold text-gray-800">{{ navigation.heading }}</h3>
        <div class="mt-5 flex-grow flex flex-col">
            <nav class="flex-1 px-2 space-y-1 bg-white" aria-label="Sidebar">
            <div v-for="(category, index) in navigation.categories" :key="index">
                <SidebarItem v-if="!category.subcategories.length" :category="category"/>
                <SidebarSection v-else-if="category.subcategories.length" @click="toggleExpansion(index)" :category="category"/>
            </div>
            </nav>
        </div>
    </div>
</template>

<script lang="ts">
export default {
    // BEFORE:
    // async mounted() {
    //     const that = this
    //     this.fetchCategories()
    //     .then(function() {
    //         that.navigation = that.$store.getters.navigation
    //     })
    // },

    // AFTER:
    async fetch() {
        await this.fetchCategories()
        this.navigation = this.$store.getters.navigation
    },
}
</script>

【讨论】:

  • 太棒了!我知道我当前的实现感觉不太对劲。现在页面加载更加无缝,代码更清晰。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-02
  • 2020-09-22
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2021-06-15
相关资源
最近更新 更多