为什么使用 vue-apollo 在两个独立组件之间共享组件数据?



我正在用vue和vue-apollo做一个新项目。

我有一个显示用户名的组件(UserShow.vue(:

<template>
<div v-if="!this.$apollo.queries.user.loading">
Your name is: {{user.firstname}}
</div>
</template>
<script>
import gql from "graphql-tag";
export default {
apollo: {
user: {
query: gql`{
user (id: 1) {
id
firstname
}
}`
}
}
}
</script>

和一个用于编辑的组件(UserEdit.vue(:

<template>
<div v-if="!this.$apollo.queries.user.loading">
Edit your name: <input v-model="user.firstname" />
</div>
</template>
<script>
import gql from "graphql-tag";
export default {
apollo: {
user: {
query: gql`{
user (id: 1) {
id
firstname
}
}`
}
}
}
</script>

这两个组件都显示在同一页面上,绝对不涉及突变。 只是这两个简单的组件。就这样

一旦我在输入字段中更改名称,用户名就会在视图中更新。

这对我来说感觉很奇怪,我不喜欢它。

Apollo 正在执行查询并填充每个组件的 vuedata()属性。但是,为什么以某种方式共享数据? 只要我不将其传递给子组件(就像输入字段中的 v-model 一样(,vue 组件中的data应该是该组件私有的。

如果我在缓存中查看我的阿波罗开发控制台,我看不到名字的变化。那么它是如何工作的呢?

如果我不想要这种行为,我只有一个奇怪的选择:

我可以像这样向查询添加另一个属性:

<template>
<div v-if="!this.$apollo.queries.user.loading">
Edit your name:
<input v-model="user.firstname" />
</div>
</template>
<script>
import userQuery from "./user";
import gql from "graphql-tag";
export default {
apollo: {
user: {
query: gql`{
user (id: 1) {
id
firstname
age         // added to create a different query
}
}`
}
}
}
</script>

向查询添加"age"会更改行为。这就更奇怪了!如何编写具有这种行为的可靠组件?还是我错过了一些关键的概念?

源代码可以在这里找到: https://github.com/kicktipp/hello-apollo

错误或功能?

我看了一下你的代码,我很确定我知道发生了什么。

如果您通读此线程,您将看到从查询返回的数据最初是 Apollo 不可变的(您不应将其用作v-model(。事实上,它曾经被冻结,因此尝试将其用作数据源会导致反应中断。

然后发生了这件事。现在查询结果是可变的,您正在更改 Apollo 的内部数据。

这就解释了为什么一个更新会立即使用相同的查询修改另一个组件的显示输出。

请尝试以下操作:

import userQuery from './user';
export default {
data() {
return { user: {} };
},
apollo: {
user: {
query: userQuery,
manual: true,
result({ data }) {
this.user = { ...data.user };
},
},
},
};

请注意以下几点:

  • userdata中初始化
  • manual: true设置user因此 Vue Apollo 不会自动设置
  • result我们使用跨页(或 Object.assign(设置this.user以避免复制引用。如果对象有多个级别,请考虑使用 cloneDeep 之类的东西。

您需要在要更改查询结果的所有位置进行类似的修改。

最新更新