Search code examples
vue.jsvuejs2vuex

How to commit received data to Vue store?


I'm trying to:

  • get element's data @click using getDetails method and put it into fileProperties: []

  • and then send that data to store using fileDetails computed property

This worked for my other components which have v-model and simple true/false state, but I'm not sure how to send the created by the method array of data to the store properly.

In other words, how do I make this computed property to get the data from fileProperties: [] and commit it to store? The fileDetails computed property below is not committing anything.

Code:

  [...]

  <div @click="getDetails(file)"></div>

  [...]


<script>
  export default {
    name: 'files',
    data () {
      return {
        fileProperties: []
      }
    },
    props: {
      file: Object
    },
    methods: {
      getDetails (value) {
        this.fileProperties = [{"extension": path.extname(value.path)}, 
                              {"size": this.$options.filters.prettySize(value.stat.size)}]
      }
    },
    computed: {
      isFile () {
        return this.file.stat.isFile()
      },
      fileDetails: {
        get () {
          return this.$store.state.Settings.fileDetails
        },
        set (value) {
          this.$store.commit('loadFileDetails', this.fileProperties)
        }     
      }
    }
  }
</script>

store module:

const state = {
    fileDetails: []
}

const mutations = {
    loadFileDetails (state, fileDetails) {
        state.fileDetails = fileDetails
    }
}

Example on codepen:

https://codepen.io/anon/pen/qxjdNo?editors=1011

In this codepen example, how can I send over the dummy data [ { "1": 1 }, { "2": 2 } ] to the store on button click?


Solution

  • You are never setting the value for fileDetails, so the set method of the computed property is never getting called. Here's the documentation on computed setters.

    If the fileProperties data is really just the same as the fileDetails data, then get rid of it and set fileDetails directly in your getDetails method.


    Here's a working example:

    const store = new Vuex.Store({
      state: {
        fileDetails: null
      },
      mutations: {
        loadFileDetails (state, fileDetails) {
          state.fileDetails = fileDetails
        }
      }
    })
    
    new Vue({
      el: '#app',
      store,
      data() {
        return {
          fileProperties: null
        }
      },
      methods: {
        getDetails (value) {
          this.fileDetails = [{"1": 1}, {"2": 2}]
        }
      },
      computed: {
        fileDetails: {
          get () {
            return this.$store.state.fileDetails
          },
          set (value) {
            this.$store.commit('loadFileDetails', value)
          }     
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
    <div id="app">
      <h1>element data:</h1>
      {{fileDetails}}
    
      <hr>
    
      <h1>store data:</h1>
      <p>(should display the same data on button click)</p>
      {{fileDetails}}
    
      <hr>
    
      <button @click="getDetails">btn</button>
    </div>