动态/异步组件渲染

时间:2019-02-27 17:06:27

标签: javascript vue.js vuejs2 vue-component

我对VueJS还是陌生的,并且已经在框架中玩了几天。

我正在构建一种具有基于小部件的外观的仪表板,而我遇到的问题是,当用户向仪表板中添加大量小部件时,由于小部件会同时进行调用,因此页面加载会出现问题API检索数据的子集。

下面是这个概念,以使您更好地了解我在做什么。 (这是保持代码整洁简单的一个简短主意。)

Home.vue

<template>
  <div class="Home">
    <h1>Homepage</h1>
    <div v-for="w in widgets">
        <component :is="widget"></component>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Home',
  mounted() {

    for (var i = 0; i < availableWidgets; i++) {
        widgets.push(availableWidgets);
    }

  },
};
</script>

小部件1

<template>
  <div class="Widget1">
    <span>Widget 1</span>
  </div>
</template>

<script>

export default {
  name: 'Widget1',
  mounted() {
    //Get data from API and render
  },
};
</script>

小部件2

<template>
  <div class="Widget2">
    <span>Widget 2</span>
  </div>
</template>

<script>

export default {
  name: 'Widget2',
  mounted() {
    //Get data from API and render
  },
};
</script>

如您所见,我有点是在加载小部件并根据用户在其仪表板上的内容动态添加它们。

我遇到的问题是小部件1和小部件2(在我的情况下有20-30个小部件)将进行API调用,并且在加载1或2个小部件时可以正常工作。但是一旦页面增长很多,页面上就会有10个小部件,一切都会开始滞后。

您建议采取什么措施来提高绩效?是否可以一次加载一个组件,然后再加载第二个组件,依此类推?我当时在考虑添加异步调用,但这不会阻止同时加载组件吗?

期待您的反馈和帮助。

1 个答案:

答案 0 :(得分:0)

一个常见的模式是让第一个渲染不包含数据,然后在每次输入数据时重新渲染。浏览器将确保不会同时运行太多网络请求,因此不应有延迟从中解脱。您只是感觉到滞后,因为您的组件要等到数据加载后才渲染。

我建议使用Axios之类的东西,它使用promises并使其易于创建异步http请求,同时又保持代码可读性。

<template>
  <div class="widget graph">
    <div v-if="loading">
      <span>Loading...</span>
      <img src="assets/loader.svg">
    </div>
    <div v-else>
      <!-- Do whatever you need to do whenever data loads in -->
    </div>
  </div>
</template>

<script>
export default {
  name: 'WidgetGraph',

  data () {
    return {
      loading: true,
      error: null,
      graphData: {}
    }
  },

  created () {
    this.loadData();
  },

  methods: {
    loadData () {
      return axios.get(...).then((data) => {
        this.loading = false;
      }).catch(() => {
        this.error = 'Something went wrong.... Panic!';
        this.loading = false;
      });
    }
  }
}
</script>

<style>

</style>