как получить данные из API в vuex с помощью axios?

у меня есть данные, взятые из API laravel, и вот мой код в состоянии.js

import axios from 'axios'
import {apiPostGet} from '../api/api'
export default {
  data: axios({
    method: 'GET',
    url: apiPostGet('Kategori')
  }).then(
    response => {
      return response.data.kategori
    }
  ).catch(
    error => {
      return error.response
    }
  )
}

и это мой код в gteeters.js

export default {
  datas: state => {
    return state.data
  }
}

и это мой код в индекс.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import getters from './getters'

Vue.use(Vuex)

export default new Vuex.Store({
   state,
   getters
})

and this picture from dev tool vue js

1 ответов


Data крюк должен возвращаться синхронно. Вы должны добавить загрузку в created или mounted и просто добавьте свойства в данные / состояние, поэтому реактивность работает.

загрузка данных с Axios должна быть triggerd с действием, потому что это asynch. Мутации должны выполняться синхронно. Я добавил начальную загрузку в created. (mounted также будет работать.)

я использовал помощник Vuex mapState для сопоставления свойств состояния с компонентом. Использование геттеров также будет работать, но mapState легче написать.

пожалуйста, посмотрите на демо ниже или это скрипка.

также раскомментируйте код ниже версии Vuex в скрипке и прокомментируйте приложение выше, чтобы увидеть, как Axios работает с Vuex для лучшего понимания.

const URL = 'https://jsonplaceholder.typicode.com/posts';

const store = new Vuex.Store({
  state: {
    posts: [],
    loading: true
  },
  actions: {
    loadData({
      commit
    }) {
      axios.get(URL).then((response) => {
        // console.log(response.data, this)
        commit('updatePosts', response.data)
        commit('changeLoadingState', false)
      })
    }
  },
  mutations: {
    updatePosts(state, posts) {
      state.posts = posts
    },
    changeLoadingState(state, loading) {
      state.loading = loading
    }
  }
})

new Vue({
  el: '#app',
  computed: Vuex.mapState(['posts', 'loading']),
  store,
  created() {
    //console.log(this.$store)
    this.$store.dispatch('loadData') // dispatch loading
  }
})

/*
	//example with-out vuex
  
new Vue({
	el: '#app',
	data() {
  	return {
    	loading: true,
      posts: [] // add posts here so reactivity is working, also undefined would be OK
    }
  },
  created() {
  	//this.loading = true --> not needed already set in data
  	axios.get(URL).then((response) => {
    	// console.log(response.data, this)
      this.posts = response.data
      this.loading = false
    })
  }
})

*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js"></script>
<div id="app">
  <div v-if="loading">
    loading...
  </div>
  <div v-else>
    <ul>
      <li v-for="post in posts">
        <h1>
          {{post.title}}
        </h1>
        <p>
          {{post.body}}
        </p>
      </li>
    </ul>
  </div>
</div>