如何按特定顺序加载vuejs组件?

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

我有一个父组件,其中包含两个子组件。 两个子组件之一将通过 axios 调用将数据存储在数据库中。 第二个子组件将需要查询数据库来获取这些数据。

如何确保在第一个插入数据之前第二个不会“启动”?

我应该使用自定义事件吗?

vue.js vue-component
3个回答
3
投票

我会使用

v-if
条件渲染与
async/await
,类似:

<first-component />
<second-component v-if="didFirstComponentFinish" />

data() {
  return {
    didFirstComponentFinishAjax: false
  }
}, ...
async methods: { //or where you make your AJAX call
  await yourAjaxCall

  this.didFirstComponentFinishAjax = true //after the call is finished the component will show

  // your AJAX logic
}

当然可以通过 props、vuex 或任何你拥有的逻辑来传递你的 AJAX 数据。


0
投票

您只需要使用类似 v-if="dataFromFirstChild"

示例:

HTML:

<first-child></first-child>
<second-component v-if="dataFromFirstChild" >

脚本:

data() {
   return {
      dataFromFirstChild: false
   }
},
beforeMount(): { 
    axios.get('...')
    .then(function (response){

        //now do whatever you want with the response             

        this.dataFromFirstChild = true; //render the secondChild now
    }.bind(this)))
    .catch(function(error) {
        console.log(error);
    });
}

0
投票

您可以向在数据库中存储数据的子级添加一个发射,以将事件“加载”传递给父级,当数据存储的所有功能都已执行时,该事件将被触发(并发射)。

然后在父级中,捕获该事件并为其分配一个回调以对其进行引用,这样我们就可以将其与第二个子级中的 v-if 绑定一起使用。因此,当第二个子级执行 axios 调用时,第一个子级已经完成了数据库工作(如果没有,第二个子级甚至还不会被创建)。

//Inside the 1st child:

//define emits
const emits = defineEmits(['load']);

onMounted(() => {
    //your database operations
    //...
   
    emits('load');
});

//Now on parent
<script setup>
    import { ref } from 'vue'
    const firstChildLoaded = ref(false);
</script>

<template>
    <FirstChild @load="firstChildLoaded = true" />
    <SecondChild v-if="firstChildLoaded" />
</template>

可以对一组组件执行此操作,因此我们可以使用带有 v-for 和 :is 指令的特殊组件按顺序渲染所有组件。当您需要一个接一个地加载页面的组件时,这可能很有用。唯一的要求是让“加载”在数组的每个组件中发出。一个例子:

//code in the parent that will contain the components loaded in order
const components = reactive([
    {
        name: 'MyHeader',
        component: shallowRef(MyHeader),
        loaded: false
    },
    {
        name: 'RouterView',
        component: shallowRef(RouterView),
        loaded: false
    },
    {
        name: 'MyFooter',
        component: shallowRef(MyFooter),
        loaded: false
    },

]);
<template v-for="comp in components">

  <component 
      v-if="previousLoaded(comp.name, components)" 
      @load="components[getIndex(comp.name, components)].loaded = true" 
      :is="comp.component">
  </component>

</template>

使用该结构,组件数组将按顺序一个接一个地加载。这可能有更好的方法,但这是我为自己找到的解决方案并想分享它。 (我的问题是,当页面重新加载时,页脚在其他组件之前加载,使滚动变得奇怪,并在我不想要的时候通过 js 触发一些 css 动画)

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