web-dev-qa-db-fra.com

comment obtenir des données d'API dans Vuex en utilisant Axios?

J'ai des données tirées de l'API laravel, et voici mon code dans state.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
    }
  )
}

et ceci est mon code dans gteeters.js

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

et ceci est mon code dans index.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

8
tejoprabowo

Data hook doit retourner de manière synchrone. Vous devez ajouter le chargement à created ou mounted et simplement ajouter les propriétés à data/state pour que la réactivité fonctionne.

Le chargement des données avec Axios doit être déclenché par une action car elle est asynchrone. Les mutations doivent être synchrones. J'ai ajouté le chargement initial dans created. (mounted fonctionnerait aussi.)

J'ai utilisé l'assistant Vuex mapState pour mapper les propriétés d'état au composant. L'utilisation de getters fonctionnerait aussi, mais mapState est plus facile à écrire.

Veuillez consulter la démo ci-dessous ou ce violon .

Décommentez également le code situé sous la version de Vuex dans le violon et commentez l’application ci-dessus pour voir comment Axios fonctionne avec Vuex pour une meilleure compréhension.

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>

11
AWolf

J'utiliserais la solution de AWolf, mais avec une gestion des erreurs légèrement améliorée dans la méthode loadData

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>

       function getUrlParams (){
          var url_params = new URLSearchParams();
          if( window.location.toString().indexOf("?") != -1) {
             var href_part = window.location.search.split('?')[1]
             href_part.replace(/([^=&]+)=([^&]*)/g,
                function(m, key, value) {
                   var attr = decodeURIComponent(key)
                   var val = decodeURIComponent(value)
                   url_params.append(attr,val);
             });
          }
          // for(var pair of url_params.entries()) { consolas.log(pair[0]+ '->'+ pair[1]); }
          return url_params ;
       }


      function getServerData (url, urlParams ){
          if ( typeof url_params == "undefined" ) { urlParams = getUrlParams()  }
          return axios.get(url , { params: urlParams } )
          .then(response => {
             return response ;
          })
          .catch(function(error) {
             console.error ( error )
             return error.response;
          })
       }

    // Action !!!
    getServerData(url , url_params)
        .then( response => {
           if ( response.status === 204 ) {
              var warningMsg = response.statusText
              console.warn ( warningMsg )
              return
           } else if ( response.status === 404 || response.status === 400) {
              var errorMsg = response.statusText // + ": "  + response.data.msg // this is my api
              console.error( errorMsg )
              return ;
           } else {
              var data = response.data
              var dataType = (typeof data)
              if ( dataType === 'undefined' ) {
                 var msg = 'unexpected error occurred while fetching data !!!'
                 // pass here to the ui change method the msg aka
                 // showMyMsg ( msg , "error")
              } else {
                 var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
                 // call here the ui building method
                 // BuildList ( items )
              }
              return
           }

        })




    </script>
0
Yordan Georgiev