问题描述
我刚刚发布了我的应用,包括用于结帐管理的 Nuxt.js 前端、Strapi CMS 和 Headless Shopify。为了实现全局购物车组件,我需要在 init 上加载所有产品,如下面所示。数据来自 CMS。
./plugins/products.js
// Load products on init
export default async ({app}) => {
await app.store.dispatch('shop/products/setProducts');
}
./store/products.js
export const actions = {
async setProducts(state) {
const allProducts = await this.$axios.$get('/products');
state.commit('setProducts',allProducts);
},
CMS 正在通过 GraphQL/Apollo 客户端从 Shopify Storefront API 获取数据,如下所示:
./controllers/product.js
async find(ctx) {
let entities;
if (ctx.query._q) {
entities = await strapi.services.product.search(ctx.query);
} else {
entities = await strapi.services.product.find(ctx.query);
}
for (entity of entities) {
const graphId = btoa('gid://shopify/Product/' + entity.shopifyId);
try {
await client.query({
query: gql`
query {
node(id: "${graphId}") {
... on Product {
id
title
productType
variants(first: 250) {
edges {
node {
title
id
availableForSale
sku
priceV2 {
amount
currencyCode
}
compareAtPriceV2 {
amount
currencyCode
}
requiresShipping
selectedOptions {
name
value
}
}
}
}
}
}
}`
}).then((product) => {
entity.shopify = {
id: product.data.node.id,product_type: product.data.node.id,variants: product.data.node.variants,}
});
} catch (e) {
console.log(e);
}
}
return entities.map(entity => sanitizeEntity(entity,{model: strapi.models.product}));
},},
阿波罗设置:
const ApolloClient = require('apollo-boost').default;
const fetch = require('node-fetch');
const {InMemoryCache,gql} = require('apollo-boost');
const client = new ApolloClient({
uri: 'https://santras.myshopify.com/api/graphql',cache: new InMemoryCache(),fetch: fetch,headers: {
'X-Shopify-Storefront-Access-Token': 'e908298c617e035c47c62ae449887b3c'
}
});
最大的问题是,从 shopify api 加载所有产品和变体非常慢。没有缓存所有产品的第一次加载需要长达 20000 毫秒。缓存后,/products
的每个请求最多需要 1.500 秒。
现在,很多测试用户都遇到了 nuxt 应用加载时间过长的问题,正因为如此。在显示某些内容之前,有一个 nuxt 加载圈持续 5-10 秒。有没有办法在加载来自插件的数据时已经显示内容?
解决方法
尝试查看 Nuxt 中的 Fetch Hook。这可以获取异步数据。
在组件方面,它公开了 $fetchState ,其中包含以下状态,特别是 $fetchState.pending 在获取正在进行时为真。它允许您在等待从 API 取回数据的同时放置一些数据。
<template>
<div v-if="$fetchState.pending">Fetching data from Shopify ...</div>
<div v-else>
<div v-for="product in products" ... />
</div>
</template>
<script>
export default {
data() {
return {
products: []
}
},async fetch() {
this.products= await strapi.services.product.search(this.query);
}
}
</script>