【问题标题】:Skeleton loader component骨架加载器组件
【发布时间】:2020-12-11 13:15:30
【问题描述】:

我是 VueJS 的新手,我来找你看看我所做的是否可行。

在加载组件时,我更喜欢显示预加载器,而不是旧数据。 我喜欢骨架加载器的想法,而不是简单的微调器。

现在我在 store 中有一个 state,默认为 null,我有一个用于设置加载的突变和一个 getter。 为了避免视觉错误,从路由器开始,我使用 beforeEach 将加载状态初始化为 true,以便默认情况下组件开始加载!

然后,在我看来,我导入了 Loader 组件及其 svg 和样式。 我把它放在需要显示的组件上,条件很简单 v-if="!getLoading" 和 v-if="getLoading"。

问题是我觉得我在修补百叶窗、beforeach 并用条件显示这个组件?

如果有人能给我一些建议,或者批准这种做法,我会很放心!

这是一个简单的Loader组件的代码

<template>
    <content-loader
        :height="78"
        :width="390"
        :speed="4"
        primaryColor="#f2f6fe"
        secondaryColor="#e0eafa"
    >
        <rect x="9" y="20" rx="4" ry="4" width="142" height="13" />
        <rect x="316.38" y="5.38" rx="5" ry="5" width="68" height="68" />
        <rect x="9" y="46" rx="4" ry="4" width="75.26" height="13.26" />
    </content-loader>
</template>

<script>
import { ContentLoader } from "vue-content-loader"

export default {
    components: {
        ContentLoader
    }
}
</script>

商店代码

const state = {
    loading: null,
}

const mutations = {
    SET_LOADING: (state, payload) => {
        state.loading = payload;
    },
}

const getters = {
    getLoading(state) {
        return state.loading;
    }
}

我认为的使用示例:有条件

<div class="col-12 col-lg-4 col-xl-3 col-md-6" v-if="getLoading"> // the condition
                        <div class="card animate-up-2">
                            <div class="card-body">
                            // the component
                                <StatsLoader></StatsLoader>
                            </div>
                        </div>
                    </div>
                    <div class="col-12 col-lg-4 col-xl-3 col-md-6" v-if="!getLoading"> // the condition
                        <div class="card animate-up-2">
                            <div class="card-body">
                                <div class="d-flex align-items-center justify-content-between">
                                    <div>
                                        <h3 class="font-weight-bold text-uppercase">5 %</h3>
                                        <div class="d-flex d-sm-block d-lg-flex align-items-end">
                                            <p class="mb-0 mr-2 text-muted">API usage</p>
                                        </div>
                                    </div>
                                    <div>
                                        <div class="avatar avatar-lg">
                                            <div class="avatar-title sred sbg-soft-red rounded">
                                                <i class="fad fa-project-diagram"></i>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    如果这是在所有路由上使用的全局加载器,您可以将其包装在一个组件中并在任何地方使用该组件。使用named slots 管理您的模板。 Loader 组件示例:

    Loader.vue

    <template>
       <div>
         <slot name='loading' v-if='getLoading'>
            <StatsLoader></StatsLoader>
         </slot>
         <slot name='content v-if='!getLoading'></slot>
       </div>
    </template>
    <script>
      import StatsLoader from '@/components/StatsLoader.vue';
      export default {
        name: 'Loader',
        props: {
          isLoading: {
            type: Boolean,
            default: null
          }
        },
        computed: {
          getLoading() {
            return this.isLoading === null ? this.$store.state.loading : this.isLoading;
          }
        },
        components: {
          StatsLoader
        }
      }
    </script>
    

    此外,全局注册此组件会很有用,因此您无需将其包含在所有路由中。你可以在你的主入口文件中使用Vue.component

    import Loader from '@/components/Loader.vue';
    
    Vue.component('Loader', Loader);
    

    你可以像这样重写你当前的组件模板:

    <Loader>
      <template v-slot:loader>
        <!-- Use a different loader here for this page maybe -->
      </template>
      <template v-slot:content>
        <div class="card animate-up-2">
          <div class="card-body">
             <div class="d-flex align-items-center justify-content-between">
                <div>
                   <h3 class="font-weight-bold text-uppercase">5 %</h3>
                   <div class="d-flex d-sm-block d-lg-flex align-items-end">
                      <p class="mb-0 mr-2 text-muted">API usage</p>
                   </div>
                </div>
                <div>
                   <div class="avatar avatar-lg">
                      <div class="avatar-title sred sbg-soft-red rounded">
                         <i class="fad fa-project-diagram"></i>
                      </div>
                   </div>
                </div>
             </div>
          </div>
       </div>
      </template>
    </Loader>
    

    如果您不想依赖全局加载器,也可以使用&lt;Loader :is-loading='isPageLoading' /&gt;

    【讨论】:

    • SVG 不同,我根据形状进行调整,因此每个 SVG 有 1 个组件。我用它来制作一个组件:create-vue-content-loader.netlify.app 如果我使用插槽,在我看来我会得到很多 SVG,而且我认为它更不干净,你觉得呢?编辑:我看错了结构,如果我理解得很好,自定义 svg 可以在撰写时保留,并将包含在插槽中!
    • 所以基本上你正在为你正在创建的所有组件创建一个骨架,对吗?在这种情况下,我建议采用类似的模式。您编写正常的组件代码,一旦完成,将其包装在 Loader 组件中,并在 loader 插槽中使用您的骨架加载器。您还可以为该特定加载器提供不同的条件来呈现内容。
    • 如果我理解得很好,我需要创建一个带有 2 个插槽的第一个组件,一个用于自定义 SVG,另一个用于显示真实内容(html 结构),然后,我将其放入视图和我将 SVG 放在第一个插槽中,将 html 内容放在第二个插槽中。 isLoading 与否的条件,在包含 2 个插槽的组件的视图中,对吗? (对不起我的英语不好:()
    • 是的,你快到了。只有 isLoading 条件是所有页面中可用的全局布尔值。如果isLoading 依赖于您页面中的某些内容,您可以将其传递给&lt;Loader /&gt; 组件。必须修改此当前答案以方便接受加载条件作为道具,如果未定义任何内容,则回退到商店。
    猜你喜欢
    • 2022-11-28
    • 1970-01-01
    • 2021-09-03
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多