Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
637 views
in Technique[技术] by (71.8m points)

api - Vue structuring with Vuex and component-specific data

I see a lot of Vue.js projects using this structure:

├── main.js
├── api
│   └── index.js
│   └── services           #containing files with api-calls
│       ├── global.js
│       ├── cart.js
│       └── messages.js
├── components
│   ├── Home.vue
│   ├── Cart.vue
│   ├── Messages.vue
│   └── ...
└── store
    ├── store.js
    ├── actions.js  #actions to update vuex stores
    ├── types.js
    └── modules
        ├── global.js
        ├── cart.js
        └── ...

(An example with this structure is 'Jackblog'.)

So, for example, Cart.vue wants to update the inCart data in Vuex. To do that, the Cart imports actions.js:

import { inCart } from '../../store/actions'

The actions.js imports the api's index.js so it can connect to the api. And then it updates the values in the Vuex store.

Ok, so that is clear for me. But now, I want to work on the Messages.vue module. This module should connect to the api as well to get all the messages, but it is not necessary to store the results in Vuex. The only component that needs the data is Messages.vue itself, so it should be stored in the component's data() only.

Question: I can't import actions.js inside Messages.vue because the action shouldn't update Vuex. But I can't move the actions.js to the api directory, because that breaks the logic of putting all files that add data to the store in the store-directory. Besides that, the logic should be placed inside Messages.vue. For example when the api returns an error, a local error-constant should be set. So it cannot be handled by a separate file.

What is the recommended application structure for making api calls and store them in vuex or local data()? Where to place the actions file, the api files, and so on? When looking to the Jackblog example it supports Vuex data only. How to restructure this to support both?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am using axios as HTTP client for making API calls, I have created a gateways folder in my src folder and I have files for each backend, creating axios instances, like following

myApi.js

import axios from 'axios'
export default axios.create({
  baseURL: 'http://localhost:3000/api/v1',
  timeout: 5000,
  headers: {
    'X-Auth-Token': 'f2b6637ddf355a476918940289c0be016a4fe99e3b69c83d',
    'Content-Type': 'application/json'
  }
})

These same instances are used in both component and vuex actions to get the data, following are details of both ways.

Populating component data

If the data is being used only in the component, like your case of Messages.vue, you can have a method which will fetch data from the api like following:

export default {
  name: 'myComponent',
  data: () => ({
    contents: '',
    product: []
  }),
  props: ['abc'],
  methods: {
    getProducts (prodId) {
       myApi.get('products?id=' + prodId).then(response => this.product = response.data)
       },
       error => {
          console.log('Inside error, fetching products failed')
          //set error variable here
       })
    }
    ..... 

Populating Vuex data

If you are maintaining product related data in a dedicate vuex module, you can dispatch an action from the method in component, which will internally call the backend API and populate data in the store, code will look something like following:

Code in component:

methods: {
 getProducts (prodId) {
     this.$store.dispatch('FETCH_PRODUCTS', prodId)
  }
}

Code in vuex store:

import myApi from '../../gateways/my-api'
const state = {
  products: []
}

const actions = {
  FETCH_PRODUCTS: (state, prodId) => {
    myApi.get('products?id=' + prodId).then(response => state.commit('SET_PRODUCTS', response))
  }
} 

// mutations
const mutations = {
  SET_PRODUCTS: (state, data) => {
    state.products = Object.assign({}, response.data)
  }
}

const getters = {
}

export default {
  state,
  mutations,
  actions,
  getters
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...