API композиции vue 2 и вычисляемые свойства

Я новичок в vue, но не понимаю, почему никто не может ответить на этот вопрос. Я бы подумал, что это просто, но я нигде не могу об этом говорить. У меня есть метод getCategory, который использует Apollo для запроса нашего API-интерфейса graphQL. Логика выглядит так:

      import { useQuery, useResult } from "@vue/apollo-composable";
import * as getCategoryBySlug from "@graphql/api/query.category.gql";

export function useGetCategory(slug: string) {
  const { result, loading, error } = useQuery(getCategoryBySlug, { slug });
  const category = useResult(result, null, (data) => data.categoryBySlug);
  return { category, loading, error };
}

Когда я хочу использовать это в компоненте, я могу просто сделать это:

      import { computed, defineComponent } from "@vue/composition-api";

import { useGetCategory } from "@logic/get-category";
import CategoryTitle from "@components/category-title/category-title.component.vue";
import Products from "@components/products/products.component.vue";

import { defineComponent } from "@vue/composition-api";

import { useGetCategory } from "@logic/get-category";
import CategoryTitle from "@components/category-title/category-title.component.vue";
import Products from "@components/products/products.component.vue";

export default defineComponent({
  name: "Categories",
  components: { CategoryTitle, Products },
  setup(_, context) {
    const { category, loading, error } = useGetCategory(
      context.root.$route.params.slug
    );

    return { category, loading, error };
  },
});

И это нормально. Затем в моем шаблоне я могу сделать то, что мне нужно, вот так:

      <template>
  <div>
    <category-title v-if="category" :category="category"> </category-title>
    <base-loader :loading="loading"> </base-loader>
    <products :category="category" v-if="category"></products>
  </div>
</template>

<script src="./category.component.ts" lang="ts"></script>
<style src="./category.component.scss" lang="scss" scoped></style>

Теперь возникает проблема (которая, на мой взгляд, должна быть очень простой). Мне нужно обрабатывать изменения маршрута, в частности, слизняк. Итак, я изменил свой код на этот:

      import { computed, defineComponent } from "@vue/composition-api";

import { useGetCategory } from "@logic/get-category";
import CategoryTitle from "@components/category-title/category-title.component.vue";
import Products from "@components/products/products.component.vue";

export default defineComponent({
  name: "Categories",
  components: { CategoryTitle, Products },
  setup(_, context) {
    const result = computed(() => {
      return useGetCategory(context.root.$route.params.slug);
    });

    return { result };
  },
});

что означает, что мне нужно обновить свой шаблон до следующего:

      <template>
  <div v-if="result">
    <category-title
      v-if="result.category.value"
      :category="result.category.value"
    >
    </category-title>
    <base-loader :loading="result.loading.value"> </base-loader>
    <products
      :category="result.category.value"
      v-if="result.category.value"
    ></products>
  </div>
</template>

<script src="./category.component.ts" lang="ts"></script>
<style src="./category.component.scss" lang="scss" scoped></style>

Что просто уродливо. Мой вопрос в том, могу ли я деструктурировать вычисленное свойство или что-то в этом роде, чтобы мой шаблон оставался таким же, как был?

1 ответ

Вы можете деструктурировать объект, возвращаемый вашим, но вы потеряете реактивность ( category, loading, error переменные, созданные в результате деструктуризации, не будут обновлены, когда computed переоценивает)

Вы хотите использовать возможность Vue Apollo для обновления запроса при изменении его переменных.

          import { useQuery, useResult } from "@vue/apollo-composable";
    import * as getCategoryBySlug from "@graphql/api/query.category.gql";

    export function useGetCategory(params) {
      const { result, loading, error } = useQuery(getCategoryBySlug, params);
      const category = useResult(result, null, (data) => data.categoryBySlug);
      return { category, loading, error };
    }

в компоненте ...

          import { computed, defineComponent } from "@vue/composition-api";

    import { useGetCategory } from "@logic/get-category";
    import CategoryTitle from "@components/category-title/category-title.component.vue";
    import Products from "@components/products/products.component.vue";

    export default defineComponent({
      name: "Categories",
      components: { CategoryTitle, Products },
      setup(_, context) {
        const params = computed(() => 
          return {
             slug: context.root.$route.params.slug
          }
        ) 
       
        const { category, loading, error } = useGetCategory(params);
      },
    });
Другие вопросы по тегам