#vuejs2 #vue-composition-api #vue-apollo
Вопрос:
Возможно, это из-за недостатка знаний, но я, похоже, сталкиваюсь с этой проблемой, что бы я ни делал. У меня есть этот компонент, который я хочу запрашивать всякий раз, когда изменяется пуля маршрута. Изначально все было устроено так:
import {
computed,
defineComponent,
getCurrentInstance,
ref,
} from "@vue/composition-api";
import Brands from "@components/brands/brands.component.vue";
import Chooser from "@components/chooser/chooser.component.vue";
import Products from "@components/products/products.component.vue";
import { useListProducts } from "./list-products";
import { useSearchBrands } from "@logic/search-brands";
import { useGetCategory } from "@logic/get-category";
export default defineComponent({
name: "ProductList",
components: { Brands, Chooser, Products },
setup() {
const instance = getCurrentInstance();
const request = computed(() => {
return {
searchTerm: "*",
itemsToShow: 12,
filters: [
{
key: "Categories[]/Slug",
value: `'${instance.proxy.$route.params.categorySlug}'`,
},
],
includePartialMatches: false,
};
});
const orderBy = ref([
{ key: "InVenue", value: "desc" },
{ key: "Promoted", value: "desc" },
]);
const { category, categoryError, categoryLoading } =
useGetCategory(instance);
const {
brands,
brandError,
brandFacets,
brandsLoading,
brandsHasMoreResults,
brandsItemsToShow,
brandsTotal,
brandsFetchMore,
brandsRefetch,
} = useSearchBrands(request);
const {
products,
productError,
productFacets,
productsLoading,
productsHasMoreResults,
productsItemsToShow,
productsTotal,
productsFetchMore,
productsRefetch,
} = useListProducts(instance, orderBy);
return {
brands,
brandError,
brandFacets,
brandsLoading,
brandsHasMoreResults,
brandsItemsToShow,
brandsTotal,
category,
categoryError,
categoryLoading,
products,
productError,
productFacets,
productsLoading,
productsHasMoreResults,
productsItemsToShow,
productsTotal,
brandsFetchMore,
productsFetchMore,
brandsRefetch,
productsRefetch,
};
},
});
Похоже, это работает, когда я меняю маршруты, все меняется, как и ожидалось. Но у меня включено отслеживание, и я вижу, что при переходе на родительскую страницу (в данном случае на продукты) код снова срабатывает, но с нулевым значением, что нехорошо.
Итак, я изменил свой код на этот:
import {
computed,
defineComponent,
getCurrentInstance,
reactive,
ref,
toRefs,
watch,
} from "@vue/composition-api";
import Brands from "@components/brands/brands.component.vue";
import Chooser from "@components/chooser/chooser.component.vue";
import Products from "@components/products/products.component.vue";
import { useListProducts } from "./list-products";
import { useSearchBrands } from "@logic/search-brands";
import { useGetCategory } from "@logic/get-category";
export default defineComponent({
name: "ProductList",
components: { Brands, Chooser, Products },
setup() {
const instance = getCurrentInstance();
const categoryResult = reactive({
category: null,
categoryError: null,
categoryLoading: null,
});
const brandsResult = reactive({
brands: [],
brandError: null,
brandFacets: [],
brandsLoading: false,
brandsHasMoreResults: false,
brandsItemsToShow: null,
brandsTotal: 0,
brandsFetchMore: null,
brandsRefetch: null,
});
const productsResult = reactive({
products: [],
productError: null,
productFacets: [],
productsLoading: false,
productsHasMoreResults: false,
productsItemsToShow: null,
productsTotal: 0,
productsFetchMore: null,
productsRefetch: null,
});
const list = (slug) => {
if (!slug) return;
const request = ref({
searchTerm: "*",
itemsToShow: 12,
filters: [
{
key: "Categories[]/Slug",
value: `'${slug}'`,
},
{
key: "InnovationGuide",
value: "true",
},
],
includePartialMatches: false,
});
const orderBy = ref([
{ key: "InVenue", value: "desc" },
{ key: "Promoted", value: "desc" },
]);
Object.assign(brandsResult, useSearchBrands(request));
Object.assign(categoryResult, useGetCategory(instance));
Object.assign(productsResult, useListProducts(instance, orderBy));
};
watch(
() => instance.proxy.$route.params.categorySlug,
(slug) => list(slug)
);
list(instance.proxy.$route.params.categorySlug);
return {
...toRefs(brandsResult),
...toRefs(categoryResult),
...toRefs(productsResult),
};
},
});
Again, this looks like it works. I don’t have the issue between child and parent anymore, but the problem is, if I navigate from /products/speakers to /products/cameras I get this error:
[![enter image description here][1]][1]
I have tried many many many times to fix this and I have never been able to. It seems that vue apollo is not great and the documentation is far from perfect.
Currently, I have it setup like this:
import { useGetUser } from "@logic/get-user";
import {
ApolloClient,
InMemoryCache,
createHttpLink,
} from "@apollo/client/core";
import { setContext } from "@apollo/client/link/context";
const uri = `${process.env.VUE_APP_API_URL}/graphql`;
const link = createHttpLink({
uri,
});
const cache = new InMemoryCache();
const authLink = setContext(async (_, { headers }) => {
const user = useGetUser();
const token = user ? `Bearer ${user.token}` : "";
if (!token) return { headers: { ...headers } };
return {
headers: {
...headers,
authorization: token || "",
},
};
});
const apiClient = new ApolloClient({
link: authLink.concat(link),
cache,
});
export default apiClient;
which in my main.ts I register like this:
import apiClient from "./_core/plugins/vue-apollo-api";
new Vue({
router,
store,
vuetify,
setup() {
provide(ApolloClients, {
default: apiClient,
apiClient,
contentfulClient,
});
},
render: (h) => h(App),
}).$mount("#app");
If I try to add:
import VueApollo from "vue-apollo";
const apolloProvider = new VueApollo({
clients: {
apiClient,
contentfulClient
},
defaultClient: apiClient
});
I get a whole load of errors stating:
1: Type ApolloClient is missing the following properties from type ‘ApolloClient’: store, writeData, initQueryManager
2: Type ‘ApolloClient’ is not assignable to type ‘ApolloClient’
But no matter how many pages I search and use, I can never get this to work.
Can someone please help as it’s stopping production now and tbh, I wish I had never bothered with graphql because of it.
[1]: https://i.stack.imgur.com/oqq59.png