#javascript #vue.js #vuex #nuxt.js
#javascript #vue.js #vuex #nuxt.js
Вопрос:
Я создаю веб-магазин для хобби-проекта в Nuxt 2.5. В хранилище Vuex у меня есть модуль с состоянием «currentCart». Здесь я храню объект с идентификатором и массив продуктов. Я получаю корзину из серверной части с идентификатором, который хранится в файле cookie (с помощью js-cookie).
Я использую nuxtServerInit для получения корзины из серверной части. Затем я сохраняю его в состоянии. Затем в компоненте я пытаюсь получить состояние и отобразить количество товаров в корзине, если значение корзины равно null, я показываю «0». Это дает странные результаты. В половине случаев он правильно сообщает, сколько в нем товаров, но инструменты разработки Vuex сообщают мне, что корзина пуста. В другую половину времени отображается «0».
Сначала у меня было промежуточное программное обеспечение, которое запускало действие в магазине, которое устанавливало корзину. Это вообще не работало последовательно. Затем я попытался настроить хранилище с помощью nuxtServerInit, что на самом деле сработало правильно. По-видимому, я что-то изменил, потому что сегодня это приводит к описанной проблеме. Я не могу выяснить, почему это создает эту проблему.
nuxtServerInit:
nuxtServerInit ({ commit }, { req }) {
let cartCookie;
// Check if there's a cookie available
if(req.headers.cookie) {
cartCookie = req.headers.cookie
.split(";")
.find(c => c.trim().startsWith("Cart="));
// Check if there's a cookie for the cart
if(cartCookie)
cartCookie = cartCookie.split("=");
else
cartCookie = null;
}
// Check if the cart cookie is set
if(cartCookie) {
// Check if the cart cookie isn't empty
if(cartCookie[1] != 'undefined') {
let cartId = cartCookie[1];
// Get the cart from the backend
this.$axios.get(`${api}/${cartId}`)
.then((response) => {
let cart = response.data;
// Set the cart in the state
commit("cart/setCart", cart);
});
}
}
else {
// Clear the cart in the state
commit("cart/clearCart");
}
},
Мутация:
setCart(state, cart) {
state.currentCart = cart;
}
Средство получения:
currentCart(state) {
return state.currentCart;
}
В cart.vue:
if(this.$store.getters['cart/currentCart'])
return this.$store.getters['cart/currentCart'].products.length;
else
return 0;
Объект состояния:
const state = () => ({
currentCart: null,
});
Я ставлю консоль.регистрирует везде, чтобы проверить, где что-то пошло не так. nuxtServerInit работает, коммит «cart / setCart» запускается и содержит нужное содержимое. В получателе большую часть времени я получаю null. Если я быстро перезагружаю страницу после другой перезагрузки, я получаю правильную корзину в получателе, и компонент получает правильное количество. Инструмент разработки Vue сообщает, что состояние currentCart равно null, даже если компонент отображает данные, которые я ожидаю.
Я изменил объект состояния на «currentCart: {}», и теперь он работает большую часть времени, но каждые 3/4 перезагрузки он возвращает пустой объект. Таким образом, очевидно, что средство получения срабатывает до того, как состояние установлено, в то время как состояние устанавливается nuxtServerInit . Это верно? Если да, то почему это так и как мне это изменить?
Чего я не понимаю? Я в полном замешательстве.
Ответ №1:
Итак, вы помните тот момент, когда вы ввели проблему для запроса в Stackoverflow, и после отправки у вас появилось несколько новых идей, которые можно опробовать? Это был один из них.
Я отредактировал вопрос, чтобы сказать, что когда я менял объект состояния на пустой объект, он иногда возвращал пустой объект. Затем меня осенило, средство получения иногда запускается перед nuxtServerInit . В документации говорится:
Примечание: Асинхронные действия nuxtServerInit должны возвращать обещание или использовать async / await, чтобы позволить серверу nuxt их дождаться.
Я изменил nuxtServerInit на это:
async nuxtServerInit ({ commit }, { req }) {
...
await this.$axios.get(`${api}/${cartId}`)
.then((response) => {
...
}
await commit("cart/clearCart");
Итак, теперь Nuxt может дождаться результатов. Инструменты разработки по-прежнему показывают пустое состояние, но я думаю, что это ошибка, поскольку я могу прекрасно использовать состояние хранилища в остальной части приложения.
Ответ №2:
Заставьте сервер ждать результатов
Приведенный выше ответ сводится к утверждению.
У меня была такая же проблема, как у @Maurits, но с немного другими параметрами. Я использую не nuxtServerInit()
, а хук выборки от Nuxt. В любом случае, идея по сути такова: вам нужно заставить сервер ждать завершения сбора данных.
Вот код для моего контекста; Я думаю, это полезно для тех, кто использует перехват выборки Nuxt. Для развлечения я добавил computed
и mounted
, чтобы проиллюстрировать, что хук выборки не включается methods
.
СБОЙ:
(Я получил пустые страницы при обновлении браузера)
computed: {
/* some stuff */
},
async fetch() {
this.myDataGrab()
.then( () => {
console.log("Got the data!")
})
},
mounted() {
/* some stuff */
}
РАБОТАЕТ:
Я забыл добавить await
перед вызовом func! Теперь сервер будет ждать этого, прежде чем завершить и отправить страницу.
async fetch() {
await this.myDataGrab()
.then( () => {
console.log("Got the messages!")
})
},