Search code examples
vue.jsvuex

Unwanted Vuex store state mutation triggered


I have a mixin for my view components that I use to set the metadata for each page. I'm using Vuex to fetch the default metadata in my store. When including the mixin in each component, I add the "metadata" data attribute and I set the value to the defaultmetadata value in my store. However, when I reassign the value of "metadata" in my mixin / component, Vuex complains that I'm trying to do mutations outside of the store. But I'm just changing the value of "metadata" in my mixin. I'm not touching "defaultmetadata" in the store.

Any ideas ?

the mixin :

    import store from 'Store/store'

    export default {
      data: function () {
        return {
          metadata: store.state.defaultmetadata
        }
      },
      computed: {
        getMetaData: function () {
          return this.metadata
        }
      },
      metaInfo () {
        let res = {
          title: this.getMetaData.title,
          meta: [
            { name: 'description', content: this.getMetaData.description }
          ]
        }
        return res
      },
      methods: {
        updateMetaData: function (key, value) {
          let regex = /(<([^>]+)>)/ig
          if (this.textNotEmpty(value)) {
            this.$set(this.metadata, key, value.replace(regex, ''))
            return true
          } else {
            return false
          }
        }
      },
      beforeRouteEnter (to, from, next) {
        next(vm => {
        })
      }
    }

This line that causes the mutation on the store :

this.$set(this.metadata, key, value.replace(regex, ''))

Here, I'm setting the local data attribute "metadata". If I comment the line, Vuex stops complaining. Why does this line trigger a mutation of store data ?

[Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."

Solution

  • They still point to a same reference, which is known as shallow copy. You can use JSON.parse(JSON.stringify)) to create a deep copy

      data: function () {
        return {
          metadata: JSON.parse(JSON.stringify(store.state.defaultmetadata))
        }
      },