在Vue中将Apollo Mutations添加到Composable中

b4lqfgs4  于 2023-10-23  发布在  Vue.js
关注(0)|答案(1)|浏览(136)

我将一些Apollo突变封装在Vue的Composable中,以允许功能在多个组件中重用,但对于一个示例,我需要知道突变的参数是什么,以便我可以创建更新函数。
当我尝试在一个函数中 Package 这个变化时,我收到以下错误
错误:未找到ID为default的Apollo客户端。如果您在组件设置之外,请使用provideApolloClient()。
这并没有在可组合中提出任何其他查询/变化,因此似乎useMutation正在失去函数内的范围

  1. import gql from 'graphql-tag';
  2. export function useComposable() {
  3. const TEAMS_QUERY = gql`
  4. query Teams {
  5. teams {
  6. nodes {
  7. id
  8. name
  9. }
  10. }
  11. }
  12. `;
  13. const leaveTeam = ({ teamId, userId }) => {
  14. const { mutate } = useMutation(
  15. DELETE_TEAM_MEMBERSHIP,
  16. () => ({
  17. update(cache, { data: { deleteTeamMembership } }) {
  18. // use the function params here to update the cache
  19. let data = cache.readQuery({ query: TEAMS_QUERY });
  20. data = {
  21. ...data.teams
  22. nodes: data.teams.nodes.filter(
  23. (team) => team.id !== teamId
  24. )
  25. };
  26. cache.writeQuery({ query: TEAMS_QUERY, data });
  27. }
  28. })
  29. );
  30. return mutate({ teamId, userId });
  31. };
  32. return {
  33. leaveTeam
  34. };
  35. }

我已经将我的函数重写为以下内容(根据错误的建议),它可以按预期工作(使用安装程序中的apollo提供程序)

  1. export function useComposable() {
  2. const TEAMS_QUERY = gql`
  3. query Teams {
  4. teams {
  5. nodes {
  6. id
  7. name
  8. }
  9. }
  10. }
  11. `;
  12. const leaveTeam = ({ teamId, userId }) => {
  13. const { mutate } = provideApolloClient(apollo)(() => useMutation(
  14. DELETE_TEAM_MEMBERSHIP,
  15. () => ({
  16. update(cache, { data: { deleteTeamMembership } }) {
  17. // use the function params here to update the cache
  18. let data = cache.readQuery({ query: TEAMS_QUERY });
  19. data = {
  20. ...data.teams
  21. nodes: data.teams.nodes.filter(
  22. (team) => team.id !== teamId
  23. )
  24. };
  25. cache.writeQuery({ query: TEAMS_QUERY, data });
  26. }
  27. })
  28. ));
  29. return mutate({ teamId, userId });
  30. };
  31. return {
  32. leaveTeam
  33. };
  34. }

我也可以这样做(在这种情况下有效),这也符合预期(注意:不是在函数内部,而是直接在可组合内部)

  1. export function useComposable() {
  2. const TEAMS_QUERY = gql`
  3. query Teams {
  4. teams {
  5. nodes {
  6. id
  7. name
  8. }
  9. }
  10. }
  11. `;
  12. const { mutate: leaveTeam } = useMutation(
  13. DELETE_TEAM_MEMBERSHIP,
  14. () => ({
  15. update(cache, { data: { deleteTeamMembership } }) {
  16. // use the function params here to update the cache
  17. let data = cache.readQuery({ query: TEAMS_QUERY });
  18. data = {
  19. ...data.teams
  20. nodes: data.teams.nodes.filter(
  21. (team) => team.id !== teamId
  22. )
  23. };
  24. cache.writeQuery({ query: TEAMS_QUERY, data });
  25. }
  26. })
  27. );
  28. return {
  29. leaveTeam
  30. };
  31. }

然而,我想知道为什么范围函数被认为是Vue Apollo上下文之外的,并且需要提供它,如果有人有解释的话?
然后,可以在我的sfc中使用组合,如

  1. <script setup>
  2. import { useComposable } from './useComposable';
  3. const { leaveTeam } = useComposable();
  4. // mocked data
  5. const user = { id: 0, name: 'My Name' };
  6. const teams = [
  7. { id: 0, name: 'Team 1' },
  8. { id: 1, name: 'Team 2' },
  9. { id: 2, name: 'Team 3' }
  10. ];
  11. </script>
  12. <template>
  13. <section class="teams-list">
  14. <h1>Admin {{ user.name }}</h1>
  15. <ul>
  16. <li v-for="team in teams" :key="team.id">
  17. {{ team.name }}
  18. <button @click="leaveTeam({ teamId: team.id, userId: user.id })">
  19. Leave Team
  20. </button>
  21. </li>
  22. </ul>
  23. <section>
  24. </template>

谢谢

disho6za

disho6za1#

当创建一个组合来封装apollo功能时(我发现这对于将带有更新函数的变化与它们影响的查询一起维护它们之间的状态特别有用),看起来下面的规则很有用。

  • 直接在您的composable中预先创建所有查询和变化-可以使用composable从组件中直接调用生成的mutate()函数,传递所需的任何变量

useComposable.js

  1. export function useComposable() {
  2. const TEAMS_QUERY = gql`query Teams {
  3. teams {
  4. nodes {
  5. id
  6. name
  7. }
  8. }
  9. }`;
  10. const { mutate } = () => useMutation(
  11. DELETE_TEAM_MEMBERSHIP,
  12. () => ({
  13. update(cache, _, { variables: { teamId } }) {
  14. // use the function params here to update the cache
  15. let data = cache.readQuery({ query: TEAMS_QUERY });
  16. data = {
  17. ...data.teams
  18. nodes: data.teams.nodes.filter(
  19. (team) => team.id !== teamId
  20. )
  21. };
  22. cache.writeQuery({ query: TEAMS_QUERY, data });
  23. }
  24. })
  25. );
  26. return {
  27. mutate
  28. };
  29. }

Component.vue

  1. const team = { id: 1 };
  2. const user = { id: 1 };
  3. const { mutate } = useComposable();
  4. mutate({
  5. teamId: team.id,
  6. userId: user.id
  7. });
  • 如果需要 Package 功能,则从函数调用结果mutate()
  1. export function useComposable() {
  2. const TEAMS_QUERY = gql`
  3. query Teams {
  4. teams {
  5. nodes {
  6. id
  7. name
  8. }
  9. }
  10. }
  11. `;
  12. const { mutate } = () => useMutation(
  13. DELETE_TEAM_MEMBERSHIP,
  14. () => ({
  15. update(cache, _, { variables: { teamId } }) {
  16. // use the function params here to update the cache
  17. let data = cache.readQuery({ query: TEAMS_QUERY });
  18. data = {
  19. ...data.teams
  20. nodes: data.teams.nodes.filter(
  21. (team) => team.id !== teamId
  22. )
  23. };
  24. cache.writeQuery({ query: TEAMS_QUERY, data });
  25. }
  26. })
  27. );
  28. const leaveTeam = ({ teamId, userId }) => {
  29. // some other functionality
  30. return mutate({ teamId, userId });
  31. };
  32. return {
  33. leaveTeam
  34. };
  35. }
  • 如果你需要在一个函数中创建一个useLazyQueryuseMutation(例如,因为你要创建一个动态变化),使用provideApolloProvider和你在应用程序初始化中设置的apollo提供程序。
  1. import apollo from '@/plugins/apollo.js';
  2. export function useComposable() {
  3. const TEAMS_QUERY = gql`
  4. query Teams {
  5. teams {
  6. nodes {
  7. id
  8. name
  9. }
  10. }
  11. }
  12. `;
  13. const leaveTeam = ({ teamId, userId }) => {
  14. const { mutate } = provideApolloClient(apollo)(() => useMutation(
  15. gql`mutation LeaveTeam($teamId: Int!, $userId: Int!) {
  16. leaveTeam(input: { teamId: $teamId, userId: $userId }) {
  17. team {
  18. id
  19. }
  20. }
  21. }`,
  22. () => ({
  23. update(cache, { data: { deleteTeamMembership } }) {
  24. // use the function params here to update the cache
  25. let data = cache.readQuery({ query: TEAMS_QUERY });
  26. data = {
  27. ...data.teams
  28. nodes: data.teams.nodes.filter(
  29. (team) => team.id !== teamId
  30. )
  31. };
  32. cache.writeQuery({ query: TEAMS_QUERY, data });
  33. }
  34. })
  35. ));
  36. return mutate({ teamId, userId });
  37. };
  38. return {
  39. leaveTeam
  40. };
  41. }
展开查看全部

相关问题