来自 Vuex 的 Apollo 请求

Apollo request from Vuex

任何人都可以告诉我从哪里可以导入 apolloClient 以便我可以向 apollo 发出请求吗? 我通常会收到错误消息,要么 mutate 不是函数(即使我从 Vue 组件传入 this.$apollo

我只是想了解一下 Vue 中的事情。如果对代码和结构有任何提示,我将不胜感激

登录组件

<template>
  <div class="signIn-component">
    <form @submit.prevent="signInUser()">
      <input
        type="email"
        placeholder="Enter your email"
        v-model="formInput.email"
      />
      <input
        type="password"
        placeholder="Enter your password"
        v-model="formInput.password"
      />
      <button>Sign In</button>
    </form>
  </div>
</template>

<script>
import { createNamespacedHelpers } from "vuex";

const { mapActions } = createNamespacedHelpers("auth");

export default {
  data() {
    return {
      formInput: {
        email: null,
        password: null
      }
    };
  },
  methods: {
    // Vuex Actions
    ...mapActions(["signIn"]),
    signInUser: function() {
      // eslint-disable-next-line no-unused-vars
      this.signIn(this.formInput, this.$apollo).then(_ =>
        this.$route.push("/")
      );
    }
  }
};
</script>

<style></style>


Vuex.auth

import { apolloClient } from 'vue-cli-plugin-apollo/graphql-client';
import SignInGQL from "@/graphql/signIn.gql";

export default {
    namespaced: true,
    state: {
        token: null,
        user: {},
        authStatus: false
    },
    getters: {
        isAuthenticated: state => !!state.token,
        authStatus: state => state.authStatus,
        user: state => state.user
    },
    actions: {
        async signIn({ commit, dispatch }, formInput) {

            console.log('here');
            try {
                const { data } = await apollo.mutate({
                    mutation: SignInGQL,
                    variables: { ...formInput }
                })

                const { token } = data.signIn;
                console.log(token);
                commit('setToken', token);
                localStorage.setItem('auth-token', token);
                dispatch('setUser', token);
            } catch (e) {
                console.error(e)
            }
        },
        setUser({ commit }, token) {
            const encodedPayload = token.split('.')[1];

            const { payload } = JSON.parse(atob(encodedPayload));
            console.log('payload: ', payload);

            // TODO: Set User information 
            commit('signInUser', payload);
        }
    },
    mutations: {
        setToken(state, token) {
            state.token = token
        },
        signInUser(state, user) {
            state.authStatus = true
            state.user = { ...user }
        },
        // logOutUser(state) {
        //     state.authStatus = ''
        //     state.token = '' && localStorage.removeItem('auth-token')
        // }
    }
}

我就是这样做的,以防有人在寻找相同的答案:

import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { createApolloClient } from 'vue-cli-plugin-apollo/graphql-client'

// Install the vue plugin
Vue.use(VueApollo)

// Name of the localStorage item
const AUTH_TOKEN = 'auth-token'

// Http endpoint
const httpEndpoint = process.env.VUE_APP_GRAPHQL_HTTP || 'http://localhost:3000/graphql';

// Config
const defaultOptions = {
  // You can use `https` for secure connection (recommended in production)
  httpEndpoint,
  // You can use `wss` for secure connection (recommended in production)
  // Use `null` to disable subscriptions
  wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || null,
  // wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws://localhost:3000/graphql',
  // LocalStorage token
  tokenName: AUTH_TOKEN,
  // Enable Automatic Query persisting with Apollo Engine
  persisting: false,
  // Use websockets for everything (no HTTP)
  // You need to pass a `wsEndpoint` for this to work
  websocketsOnly: false,
  // Is being rendered on the server?
  ssr: false,

  // Override default apollo link
  // note: don't override httpLink here, specify httpLink options in the
  // httpLinkOptions property of defaultOptions.
  // httpLinkOptions: {
  //   headers: {
  //     Authorization: authHeader
  //   }
  // }

  // Override default cache
  // cache: myCache

  // Override the way the Authorization header is set
  // getAuth: (tokenName) => getUserToken(),

  // Additional ApolloClient options
  // apollo: { ... }

  // Client local data (see apollo-link-state)
  // clientState: { resolvers: { ... }, defaults: { ... } }
}

export const { apolloClient, wsClient } = createApolloClient({
  ...defaultOptions,
  // ...options,
})

// Call this in the Vue app file
export function createProvider() {
  // Create apollo client

  apolloClient.wsClient = wsClient

  // Create vue apollo provider
  const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
    defaultOptions: {
      $query: {
        fetchPolicy: 'cache-and-network',
      },
    },
    errorHandler(error) {
      // eslint-disable-next-line no-console
      console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
    },
  })

  return apolloProvider
}


This is the source I found the solution

如果您有任何建议,请随时在这里留下,谢谢!

solution repo

import { setContext } from "apollo-link-context";
import { ApolloClient, InMemoryCache, HttpLink } from "apollo-boost";
import VueApollo from "vue-apollo";

Vue.use(VueApollo);
const httpLink = new HttpLink({
  uri: "http://sebapi.com/graphql"
});
const authLink = setContext((_, { headers }) => {
  // get the authentication token from ApplicationSettings if it exists
  const token = ApplicationSettings.getString("token");
  // return the headers to the context so HTTP link can read them
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : null
    }
  };
});
// update apollo client as below
const apolloClient = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache()
});

const apolloProvider = new VueApollo({
  defaultClient: apolloClient
});

和LOGIN.VUE

<script lang="ts">

export default {
  data() {
    return {
      jwt: "",
      user: {
        identifier: "test",
        password: "123123",
      },
    };
  },
  methods: {
    handleLogin() {

      request({
        url: "http://sebapi.com/auth/local",
        method: "POST",
        headers: { "Content-Type": "application/json" },
        content: JSON.stringify({
          identifier: this.user.identifier,
          password: this.user.password,
        }),
      })
        .then(
          (response) => {
            const result = response.content.toJSON();
            console.log("Result from Server: ", result);
//ignore applicationsettings it's just a kind of localstore in nativescript
            ApplicationSettings.setString("token", result.jwt);           
          },
          (e) => {
            console.error(e);
//ignore nativateto its routing in nativescript
            this.$navigateTo(routes.login);
          }
        )
        .then(() => {
          this.$navigateTo(routes.app);
        });
    },
  },
};
</script>