Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Structuring a Vue + Vuex project

I am kind of confused here on where to place my global functions. In a lot of examples a main.js file points to an app component and this is placed somewhere within the html. This workflow would be fine for me If I were to simply contain all my logic within this app component. But I am combining components with Laravel functionality so this does not work for me.

Currently my main.js file contains a bunch of methods that I need to have access from anywhere in my app. These methods don't contain any broadcasting events so they can effectively be placed anywhere as long as they get a vue-resource instance.

My main.js file:

https://github.com/stephan-v/BeerQuest/blob/develop/resources/assets/js/main.js

Hopefully somebody can tell me where I could place my friendship methods if I were to use vuex or in general since this does not seem like best practice at all.

Thank you.

like image 960
Stephan-v Avatar asked Jun 28 '16 09:06

Stephan-v


1 Answers

Vuex manages all of the data in your application. It's a "single source of truth" for data on your front-end. Therefore, anything that changes the state of your application, such as adding a friend, or denying a friend, needs to flow through Vuex. This happens through three main function types, getters, actions, and mutations.

Check out: https://github.com/vuejs/vuex/tree/master/examples/shopping-cart/vuex

Getters are used to fetch data from storage in Vuex. They are reactive to changes, meaning if Vuex data changes, the information in your component is updated as well. You can put these in something like getters.js so that you can import them in any module you need them in.

Actions are functions that you call directly, ie. acceptFriendRequest when a user clicks the button. They interact with your database, and then dispatch mutations. In this app, all of the actions are in actions.js.

So you'd call this.acceptFriendRequest(recipient) in your component. This would tell your database to update the friend status, then you get a confirmation back that this happened. That's when you dispatch a mutation that updates the current users' list of friends within Vuex.

A mutation updates the data in Vuex to reflect the new state. When this happens, any data you are retrieving in a getter is updated as well. Here is an example of the entire flow:

import {addFriend} from './actions.js';
import {friends} from './getters.js';
new Vue({
  vuex:{
    getters:{
      friends
    }
  },
  methods:{
    addFriend
  }
}

store.js:

export default {
  state:{
    friends: []
  },
  mutations:{
    ADD_FRIEND(state, friend) {
      state.friends.push(friend);
    }
  }
}

actions.js:

export default {
  addFriend(friend){
    Vue.http.post('/users/1/friends',friend)
      .then((response)=>{
        dispatch("ADD_FRIEND", response) //response is the new friend
      })
  }
}

getters.js

export default {
  friends(state) {
    return state.friends;
  }
}

So all of these are organized into their own files, and you can import them in any component you need. You can call this.addFriend(friend) from any component, and then your getter which is accessed from this.friends will automatically update with the new friend when the mutation happens. You can always use the same data in any view in your app and know that it is current with your database.

Some misc stuff:

  • getters automatically receive state as a variable, so you can always reference the state of your Vuex store
  • mutations should never be asynchronous. Do fetching/updating in actions and then dispatch mutations just to update your data
  • creating services (or resources) using Vue Resource will make fetching/updating/deleting resources even easier. you can put these in separate files and import them in your actions.js to keep the database retrieval logic separated. Then you'd be writing something like FriendService.get({id: 1}) instead of Vue.http.get('/users/1'). see https://github.com/vuejs/vue-resource/blob/master/docs/resource.md
  • Vuex works with vue devtools for "time-traveling". You can see a list of every mutation that has taken place and rewind them/redo them. It's great for debugging and seeing where data is being changed.
like image 193
Jeff Avatar answered Nov 20 '22 06:11

Jeff