如何使用axios从vuex中的API获取数据?

how to get data from API in vuex using axios?

我从 API laravel 中获取了数据,这是我在 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
    }
  )
}

这是我在 gteeters.js

中的代码
export default {
  datas: state => {
    return state.data
  }
}

这是我在 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
})

Data hook 需要同步return。您必须将加载添加到 createdmounted,并将属性添加到数据/状态,以便反应性正常工作。

使用 Axios 加载数据需要通过操作触发,因为它是异步的。突变需要 运行 同步。我在 created 中添加了初始加载。 (mounted 也可以。)

我使用 Vuex 助手 mapState 将状态属性映射到组件。使用 getter 也可以,但 mapState 更容易编写。

请看下面的演示或这个 fiddle

同时取消注释 fiddle 中 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>

我会使用 AWolf 的解决方案,但是在 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>