Vuejs2 Vue-将apollo查询结果从父组件传递到子组件
我有一个调用apollo查询的父组件:Vuejs2 Vue-将apollo查询结果从父组件传递到子组件,vuejs2,apollo,Vuejs2,Apollo,我有一个调用apollo查询的父组件: <template> <div class="row" style="flex-wrap: nowrap; width:102%"> <BusinessContextTeamPanel :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDet
<template>
<div class="row" style="flex-wrap: nowrap; width:102%">
<BusinessContextTeamPanel :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDetailPanel>
</div>
</template>
<script>
apollo: {
business_contexts: {
query: gql`query ($businessContextId: uuid!) {
business_contexts(where: {id: {_eq: $businessContextId }}) {
id
businessContextTeams {
id
team {
name
id
}
role
}
}
}`,
variables: function() {
return {
businessContextId: this.currentContextId
}
}
}
},
</script>
这里的v-if
抛出
无法读取未定义的属性“length”
当v-for
工作时。
当我试图在子组件挂载钩子上调用的子方法(loadData()
)中使用道具时,我也会得到undefined
<script>
import Treeselect from '@riophae/vue-treeselect';
import _ from "lodash";
export default {
name: "BusinessContextTeamPanel",
components: { Treeselect },
props: ['business_contexts'],
data() {
return {
itemModel: {},
allRoles: [],
formTitle: "",
filteredTeams: [],
showNoTeamMsg: false
}
},
mounted() {
this.loadData();
},
methods: {
loadData() {
let roles = [];
_.forEach(["Admin", "Contributor", "Owner", "Master", "Viewer", "User"], function (role) {
roles.push({id: role, label: role});
});
console.log(this.business_contexts); // here I get undefined
this.allRoles = roles;
this.showNoTeamMsg = this.business_contexts.length === 0;
}
}
}
</script>
从“@riophae/vue Treeselect”导入Treeselect;
从“洛达斯”进口;
导出默认值{
名称:“BusinessContextTeamPanel”,
组件:{Treeselect},
道具:['business_contexts'],
数据(){
返回{
itemModel:{},
所有角色:[],
表格名称:“,
筛选数据组:[],
showNoTeamMsg:错误
}
},
安装的(){
这是loadData();
},
方法:{
loadData(){
让角色=[];
_.forEach([“管理员”、“贡献者”、“所有者”、“主控者”、“查看者”、“用户”],函数(角色){
roles.push({id:role,label:role});
});
console.log(this.business_contexts);//这里没有定义
this.allRoles=角色;
this.showNoTeamMsg=this.business_contexts.length==0;
}
}
}
我遗漏了什么?要么您的apollo查询不起作用,要么它没有及时准备好供子组件尝试使用 为了进行调试,在父组件的模板中添加{{business_contexts}},这样您就可以查看它了。这将确认查询是否有效 如果查询正在工作,则可能是您的子组件正在尝试在数据准备就绪之前访问数据。将您的v-if从
<div v-if="business_contexts.length > 0">
到
编辑:更好的做法是,将父组件更改为根本不尝试加载子组件,直到父组件具有以下数据:
<BusinessContextTeamPanel v-if="business_contexts" :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDetailPanel>
我可以在父级中看到{{business\u contexts}}中的数据
我也可以从子级中看到它,但是v-if
仍然会增加未定义的长度,即使您进行了更改。为什么v-if下方的v-for
正确显示了business\u上下文中的数据,但v-if崩溃了?您确定是v-if引发了该错误吗?我提供的if语句中的&&
使其短路-如果前面的部分计算结果不为true,则后面的部分将不会执行。因此,如果未定义业务上下文,那么它将不会计算business\u contexts.length>0
,因此错误消息确实不可能出现。再次检查未定义的错误现在没有从其他地方抛出;您的子组件mounted()也正在尝试在变量准备就绪之前访问它。我会更新我的答案,提供更多关于这个的信息是的,这肯定是它,你的mounted()钩子将在数据准备好之前运行。您希望延迟加载组件,直到它准备就绪。或者,您必须对子组件进行工程设计,以便在数据存在后才查找该数据-mounted()为时过早。例如,您可以从观察者处调用loadData(),也可以完全取消loadData(),将this.showNoTeamMsg和this.allRoles转换为计算属性。这意味着它们也将是反应性的,耶,你完全正确,我的想法是,道具将在孩子上马之前加载数据,关于观察者和计算值的优点,谢谢。但是仍然困扰着我为什么v-for能够正确地呈现数据?它像异步管道一样使用吗?不用担心!Vue模板对我来说仍然有点神奇,但我的理解是,它们将在对反应变量进行更改时重新加载。因此,即使出现错误,业务上下文稍后也会变为可用,模板会重新加载,此时不再出现错误
<div v-if="business_contexts && business_contexts.length > 0">
<BusinessContextTeamPanel v-if="business_contexts" :business_contexts="business_contexts"></BusinessContextTeamPanel></BusinessContextTeamDetailPanel>