在Vue中将Apollo Mutations添加到Composable中

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

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

import gql from 'graphql-tag';

export function useComposable() {
  const TEAMS_QUERY = gql`
    query Teams {
      teams {
        nodes {
          id
          name
        }
      }
    }
  `;

  const leaveTeam = ({ teamId, userId }) => {
    const { mutate } = useMutation(
      DELETE_TEAM_MEMBERSHIP,
      () => ({
        update(cache, { data: { deleteTeamMembership } }) {
          // use the function params here to update the cache
          let data = cache.readQuery({ query: TEAMS_QUERY });
          data = {
            ...data.teams
            nodes: data.teams.nodes.filter(
              (team) => team.id !== teamId
            )
          };
          cache.writeQuery({ query: TEAMS_QUERY, data });
        }
      })
    );
    return mutate({ teamId, userId });
  };

  return {
    leaveTeam
  };
}

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

export function useComposable() {
  const TEAMS_QUERY = gql`
    query Teams {
      teams {
        nodes {
          id
          name
        }
      }
    }
  `;

  const leaveTeam = ({ teamId, userId }) => {
    const { mutate } = provideApolloClient(apollo)(() => useMutation(
      DELETE_TEAM_MEMBERSHIP,
      () => ({
        update(cache, { data: { deleteTeamMembership } }) {
          // use the function params here to update the cache
          let data = cache.readQuery({ query: TEAMS_QUERY });
          data = {
            ...data.teams
            nodes: data.teams.nodes.filter(
              (team) => team.id !== teamId
            )
          };
          cache.writeQuery({ query: TEAMS_QUERY, data });
        }
      })
    ));
    return mutate({ teamId, userId });
  };

  return {
    leaveTeam
  };
}

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

export function useComposable() {
  const TEAMS_QUERY = gql`
    query Teams {
      teams {
        nodes {
          id
          name
        }
      }
    }
  `;

  const { mutate: leaveTeam } = useMutation(
    DELETE_TEAM_MEMBERSHIP,
    () => ({
      update(cache, { data: { deleteTeamMembership } }) {
        // use the function params here to update the cache
        let data = cache.readQuery({ query: TEAMS_QUERY });
        data = {
          ...data.teams
          nodes: data.teams.nodes.filter(
            (team) => team.id !== teamId
          )
        };
        cache.writeQuery({ query: TEAMS_QUERY, data });
      }
    })
  );

  return {
    leaveTeam
  };
}

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

<script setup>
import { useComposable } from './useComposable';

const { leaveTeam } = useComposable();

// mocked data
const user = { id: 0, name: 'My Name' };

const teams = [
  { id: 0, name: 'Team 1' },
  { id: 1, name: 'Team 2' },
  { id: 2, name: 'Team 3' }
];
</script>

<template>
  <section class="teams-list">
    <h1>Admin {{ user.name }}</h1>
    <ul>
      <li v-for="team in teams" :key="team.id">
        {{ team.name }}
        <button @click="leaveTeam({ teamId: team.id, userId: user.id })">
          Leave Team
        </button>
      </li>
    </ul>
  <section>
</template>

谢谢

disho6za

disho6za1#

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

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

useComposable.js

export function useComposable() {
  const TEAMS_QUERY = gql`query Teams {
    teams {
      nodes {
        id
        name
      }
    }
  }`;

  const { mutate } = () => useMutation(
    DELETE_TEAM_MEMBERSHIP,
    () => ({
      update(cache, _, { variables: { teamId } }) {
        // use the function params here to update the cache
        let data = cache.readQuery({ query: TEAMS_QUERY });
        data = {
          ...data.teams
          nodes: data.teams.nodes.filter(
            (team) => team.id !== teamId
          )
        };
        cache.writeQuery({ query: TEAMS_QUERY, data });
      }
    })
  );

  return {
    mutate
  };
}

Component.vue

const team = { id: 1 };
const user = { id: 1 };

const { mutate } = useComposable();

mutate({
  teamId: team.id,
  userId: user.id
});
  • 如果需要 Package 功能,则从函数调用结果mutate()
export function useComposable() {
  const TEAMS_QUERY = gql`
    query Teams {
      teams {
        nodes {
          id
          name
        }
      }
    }
  `;

  const { mutate } = () => useMutation(
    DELETE_TEAM_MEMBERSHIP,
    () => ({
      update(cache, _, { variables: { teamId } }) {
        // use the function params here to update the cache
        let data = cache.readQuery({ query: TEAMS_QUERY });
        data = {
          ...data.teams
          nodes: data.teams.nodes.filter(
            (team) => team.id !== teamId
          )
        };
        cache.writeQuery({ query: TEAMS_QUERY, data });
      }
    })
  );

  const leaveTeam = ({ teamId, userId }) => {
    // some other functionality
    return mutate({ teamId, userId });
  };

  return {
    leaveTeam
  };
}
  • 如果你需要在一个函数中创建一个useLazyQueryuseMutation(例如,因为你要创建一个动态变化),使用provideApolloProvider和你在应用程序初始化中设置的apollo提供程序。
import apollo from '@/plugins/apollo.js';

export function useComposable() {
  const TEAMS_QUERY = gql`
    query Teams {
      teams {
        nodes {
          id
          name
        }
      }
    }
  `;

  const leaveTeam = ({ teamId, userId }) => {
    const { mutate } = provideApolloClient(apollo)(() => useMutation(
      gql`mutation LeaveTeam($teamId: Int!, $userId: Int!) {
        leaveTeam(input: { teamId: $teamId, userId: $userId }) {
          team {
            id
          }
        }
      }`,
      () => ({
        update(cache, { data: { deleteTeamMembership } }) {
          // use the function params here to update the cache
          let data = cache.readQuery({ query: TEAMS_QUERY });
          data = {
            ...data.teams
            nodes: data.teams.nodes.filter(
              (team) => team.id !== teamId
            )
          };
          cache.writeQuery({ query: TEAMS_QUERY, data });
        }
      })
    ));
    return mutate({ teamId, userId });
  };

  return {
    leaveTeam
  };
}

相关问题