#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);
Комментариев нет:
Отправить комментарий