Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

Как вызвать action и вернуть getters во Vuex

#vuejs #axios #vuex


Задача: получить данные из JSON в хранилище Vuex и присвоить их переменной.



Данные я получаю через Axios:

loadGameData ({commit}) {   
  axios.get('table_json/game-data.json').then(response => {
    console.log(response.data);           
  }); 
}


Данные успешно получены и выводятся в консоли. Но мне нужно, чтобы содержимое JSON
записывалось в переменную. Нашла похожий вопрос, однако предложенные там решения у
меня не сработали.

// Пробовала так:
loadGameData ({commit}) {   
  axios.get('table_json/game-data.json').then(response => {
    var a = response.data;
  });

  console.log(a);
}

// ... и так:
loadGameData ({commit}) {  
  axios.get('table_json/game-data.json').then (promise => {
    var a = promise.data;
  });

  console.log(a);
}


Не работает – в обоих случаях в консоли ошибка:


  ReferenceError: 'a' is not defined.


Пожалуйста, помогите решить задачу.
    


Ответы

Ответ 1



Подобные вопросы уже задавались много раз. Если коротко и в упрощенной формулировке: в компоненте вызывается метод (action) в хранилище; этот метод выполняет асинхронный запрос (axios); результаты запроса пробрасываются (передаются) в мутации (mutations); в мутациях меняется состояние (state) хранилища; в компоненте через вычисляемое (computed) свойство происходит обновление данных. Демо с небольшими комментариями: // Список доступных мутаций (сеттеры). const SET_COLLECTION = 'SET_COLLECTION'; const store = new Vuex.Store({ // STATE - изначальное состояние. state: { collection: [], }, // GET - получить, достать. getters: { // Вернуть все записи. all: state => state.collection, // Вернуть запись по `id`. byId: state => id => state.collection.find(article => id === article.id), // Вернуть записи, // поле `field` у которых равен `val`. where: state => (field, val) => state.collection.filter(article => val == article[field]), // Вернуть записи, поле `field` у которых // равен одному из значений `values`. // Приведу полную запись, без сокращений. whereIn: function whereIn(state) { return function(field, values) { return state.collection.filter(function(article) { return values.includes(article[field]); }); } }, }, // SET - установить, задать. // Обработчики мутаций обязаны быть синхронными. // Все мутации - это сеттеры. mutations: { [SET_COLLECTION](state, collection) { state.collection = collection; }, }, // ACTION - действие. // Асинхронные запросы всегда помещаются в `action`. // Но НЕ все действия обязаны быть асинхронными. actions: { load(context) { axios.get('https://jsonplaceholder.typicode.com/posts') .then(function(response) { // Полученные результаты запроса отправляются в `mutations`. context.commit('SET_COLLECTION', response.data); }) .catch(function(error) { console.log(error); context.commit('SET_COLLECTION', []); }); } // // Либо вариант с `async/await`. // async load(context) { // try { // const response = await axios.get('https://jsonplaceholder.typicode.com/posts'); // // context.commit('SET_COLLECTION', response.data); // } catch (error) { // console.log(error); // // context.commit('SET_COLLECTION', []); // } // } } }) new Vue({ el: '#app', store, data: { checked: [8] }, computed: { // При компонентном подходе ...mapGetters(). // Теперь в компоненте доступно свойство `articles`, // которое будет автоматически обновляться // при изменениях, внесенными мутациями. ...Vuex.mapGetters({ articles: 'all', whereIn: 'whereIn' }), ids() { return this.articles.map(article => article.id); }, // Пример, когда в хранилище передается параметр. // Подробнее https://ru.stackoverflow.com/a/982247/256824. filtered() { return this.whereIn('id', this.checked) } }, mounted() { this.load(); }, methods: { // При компонентном подходе ...mapActions(). // Теперь в компоненте доступен метод: this.load(). ...Vuex.mapActions([ 'load' ]), } }); .filter { max-height: 188px; overflow-y: scroll; border: 1px solid #ccc; border-radius: 4px; background: #fafafa; padding: 8px 12px; width: 100%; box-sizing: border-box; } .filter-label { display: block; } .articles { display: flex; flex-wrap: wrap; max-width: 600px; margin: 0 auto; } .article { padding: 8px 12px; width: 50%; box-sizing: border-box; } .article-title { color: #08c; }

Выбранные идентификаторы записей {{ checked }}

{{ article.title }}

{{ article.body }}

Обновлено Добавлен пример фильтрации.

Ответ 2



loadGameData ({commit}) { axios.get('table_json/game-data.json').then( response => { var a = response.data } ); console.log(a) } Асинхронность в JavaScript: Пособие для тех, кто хочет разобраться В вашем коде console.log(a) выполняется раньше чем приходит ответ в axios, по этому и undefined. Вам нужно внутри then выполнить мутацию, чтобы поменять состояние модели. Проще говоря axios.get('table_json/game-data.json').then( response => { var a = response.data; //Именно тут доступны ваши данные и тут вы можете использовать мутацию } ); // А тут a на момент выполнения недоступно и это логично, т.к. этот код выполняется раньше нежели промис меняет статус. console.log(a);

Комментариев нет:

Отправить комментарий