【问题标题】:Vue apollo add results to arrayVue apollo 将结果添加到数组
【发布时间】:2021-10-03 12:46:45
【问题描述】:

这可能只是一个基本的 vue 问题,但我使用的是 Vue Apollo。 我有这样设置的组件:

export default defineComponent({
  name: "Products",
  components: { Product },
  props: {
    categorySlug: {
      type: String,
      required: true,
    },
  },
  setup(props) {
    const { categorySlug } = toRefs(props);
    const page = ref(1);
    const skip = ref(0);
    const result = reactive({ search: null, laoding: null, error: null });

    Object.assign(result, useListProducts(categorySlug.value, page.value));

    const more = () => {
      skip.value += 12;
      page.value += 1;

      Object.assign(result, useListProducts(categorySlug.value, page.value));
    };

    return { ...toRefs(result), ...{ skip, more } };
  },
});

如您所见,我有一个反应式对象设置,它在调用组件设置方法时被分配:

const result = reactive({ search: null, laoding: null, error: null });

Object.assign(result, useListProducts(categorySlug.value, page.value));

在我的模板中,我像这样迭代结果:

<base-fade-up class="row" :duration="0.1" tag="div">
  <v-col
    cols="12"
    xl="2"
    v-for="(product, index) in products"
    :key="product.id"
    :data-index="index"
    :data-skip="skip"
  >
    <product class="product" :product="product"></product>
  </v-col>
</base-fade-up>

我的问题是我想添加一个更多按钮:

<v-btn color="primary" @click="more()" v-if="search.hasMoreResults"
  >Show more</v-btn
>

按下时,它会执行 more() 方法:

const more = () => {
  skip.value += 12;
  page.value += 1;

  Object.assign(result, useListProducts(categorySlug.value, page.value));
};

如您所见,我现在获得了 第 2 页,因此第 1 页的产品不再位于 search 对象中。 我想做的是从第一个查询中获取产品的副本,然后在每次按下更多按钮时添加到它们。 我试过这个:

setup(props) {
  const { categorySlug } = toRefs(props);
  const page = ref(1);
  const skip = ref(0);
  const products = ref([]);
  const result = reactive({ search: null, laoding: null, error: null });

  Object.assign(result, useListProducts(categorySlug.value, page.value));

  const more = () => {
    skip.value += 12;
    page.value += 1;

    Object.assign(result, useListProducts(categorySlug.value, page.value));
  };

  products.value.push(result.search.value.items);

  return { ...toRefs(result), ...{ products, skip, more } };
},

但是当我运行这段代码时,我得到一个错误:

[Vue 警告]:data() 中的错误:“TypeError: Cannot read property 'value' of null”

在这一行抱怨result.search.value

products.value.push(result.search.value.items);

我相信这是因为承诺尚未解决。 我在 useListProducts 中使用了 Apollo 的 useResult 方法,如下所示:

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

export function useListProducts(slug: string, page = 1, itemsToShow = 12) {
  const request: {
    identifier?: string;
    searchTerm: string;
    itemsToShow: number;
    page: number;
    filters: any;
    facets: string[];
  } = {
    searchTerm: "*",
    itemsToShow,
    page,
    filters: [
      {
        key: "CategorySlug",
        value: `'${slug}'`,
      },
    ],
    facets: ["Criteria/Attribute,count:100"],
  };

  const { result, loading, error } = useQuery(listProducts, {
    search: request,
  });
  const search = useResult(result, null, (data) => data.search);
  return { search, loading, error };
}

谁能告诉我我做错了什么?

【问题讨论】:

  • 它需要仔细查看,但您不应该访问在 setup 正文中初始化时不可用的内容,除非它使用悬念。钩子(使用...)应该只出现在setup,而不是moreproducts.value.push(result.search.value.items) 属于 watch 或 watchEffect ,需要检查它们是否可用于条件语句。 const result = ... Object.assign(result ... - 这没有意义,useListProducts 已经返回了一个对象,分配给result 并没有好处,这不会使它更具反应性。
  • 感谢您的回复。我是 vue 新手,所以虽然我很欣赏你的帖子,但它对我一点帮助都没有:(

标签: vue.js apollo


【解决方案1】:

经过一番挖掘,我在文档中发现了一些关于分页的内容(这基本上就是我正在做的事情),因此我设法将我的代码调整为:

export default defineComponent({
  name: "Products",
  components: { Product },
  props: {
    categorySlug: {
      type: String,
      required: true,
    },
  },
  setup(props) {
    const { categorySlug } = toRefs(props);
    const page = ref(1);
    const skip = ref(0);
    const { search, loading, error, fetchMore } = useListProducts(
      categorySlug.value,
      page.value
    );

    const more = () => {
      skip.value += 12;
      page.value += 1;

      const request = {
        ...params,
        ...{
          page: page.value,
          filters: [
            {
              key: "CategorySlug",
              value: `'${categorySlug.value}'`,
            },
          ],
        },
      };
      fetchMore({
        variables: { search: request },
        updateQuery: (prev, { fetchMoreResult }) => {
          if (!fetchMoreResult) return prev;
          //return fetchMoreResult;
          console.log(fetchMoreResult);
          return Object.assign({}, prev, {
            search: {
              hasMoreResults: fetchMoreResult.search.hasMoreResults,
              total: fetchMoreResult.search.total,
              facets: [...prev.search.facets, ...fetchMoreResult.search.facets],
              items: [...prev.search.items, ...fetchMoreResult.search.items],
              __typename: prev["__typename"],
            },
          });
        },
      });
    };

    return { search, loading, error, skip, more };
  },
});

这满足了 Estus 在 cmets 中提到的所有内容,但确实会引发错误,我将创建一个关于该问题的新帖子:D

【讨论】:

    猜你喜欢
    • 2017-12-27
    • 2018-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 2020-02-22
    • 2021-12-24
    • 2021-06-23
    相关资源
    最近更新 更多