我有一个父组件,其中包含两个子组件。 两个子组件之一将通过 axios 调用将数据存储在数据库中。 第二个子组件将需要查询数据库来获取这些数据。
如何确保在第一个插入数据之前第二个不会“启动”?
我应该使用自定义事件吗?
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 数据。
您只需要使用类似 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);
});
}
您可以向在数据库中存储数据的子级添加一个发射,以将事件“加载”传递给父级,当数据存储的所有功能都已执行时,该事件将被触发(并发射)。
然后在父级中,捕获该事件并为其分配一个回调以对其进行引用,这样我们就可以将其与第二个子级中的 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 动画)