Using Vuex

I implemented Vuex in my project this week, I'm new to Vuex and this is what I learned.  In a Vue app when you need communication between two components, you have the following choices

One recommendation I read from the Vue Forum when someone asked about Bus vs Vuex is 

My advice would be as follows: use vuex for everything as a default, and drop back to an event bus when vuex becomes a hurdle.

The basic idea is your Vue app is a tree of components and the tree could be N layers deep, and to pass data between any two components in the tree becomes a challenge.  Events when used here and there is OK but in a large app if you add a lot of them your code becomes cumbersome.  So what the app need is a global object store to contain shared data accessible to all components and that is what Vuex is.

Here I have an issue #252, it describes that when you insert some selected images from the gallery dialog into your post and then you re-open the gallery two things should happen 1. the previously selected images should be de-selected and 2. the Edit, Delete and Insert buttons which only show up when there are selected images should be hidden, neither is happening. Not only that both should happen when the dialog is closed in most cases.

Composer with gallery open
Composer with gallery open

There are 4 ways to close the dialog

  1. Click on Insert, this should insert and de-select the images and close it
  2. Click on Close, this should de-select images and close it
  3. Press "Esc" key on keyboard, this should de-select images and close it
  4. Click anywhere outside the gallery, this should close dialog but without de-selecting the images. I find this scenario often happens by mistake not by intention.

The gallery is the child component, it contains the toolbar of buttons and a list of images.  When you select images they are stored in an array named selectedImages on this child component.  The gallery is then contained inside a dialog component which is part of the parent composer. Whether the selectedImages is empty is what controls the visibility of the three buttons on the toolbar.  When I click on Insert I pass the selected images to a method of the parent which then writes out html to the editor.  

When I click on insert I actually could easily de-select the images and empty out selectedImages because the Insert button is part of the gallery component, same with clicking the Close button.  When I press Esc on my keyboard to close the dialog though it is not as simple because that is part of the parent.  In other words the parent needs to access selectedImages on the child. 

I feel this is a great example of when you could use Vuex.

let store = new Vuex.Store({ 
   strict: true, 
   state: { 
       selectedImages: [], 
   }, 
   mutations: { 
       setSelectedImages(state, newSelectedImages) { 
           state.selectedImages = newSelectedImages; 
       }, 
       addSelectedImage(state, image) { 
           state.selectedImages.push(image); 
       }, 
       removeSelectedImage(state, idx) { 
           state.selectedImages.splice(idx, 1); 
       }, 
   }, 
   actions: { 
       selectImage: function ({ commit }, image) { 
           commit('addSelectedImage', image); 
       }, 
       deselectImage: function ({ commit }, idx) { 
           commit('removeSelectedImage', idx); 
       }, 
       emptySelectedImages({ commit, state }) { 
           commit('setSelectedImages', []); 
       }, 
   }, 
});

Then the selectedImages array breaks loose and accessible globally, thus the parent can take a hold of it and empty it when necessary

this.$store.dispatch('emptySelectedImages');