Reputation: 2945
I'm using the latest version of Nuxt JS 2.8.1 to build a hybrid app. I'm utilising the modules mode of Vuex as it's recommended to do this in order for me to save data and access it across different pages, components and layouts.
On one particular page, a settings page that I've built I have a Vuetify switch, essentially a toggle which will push a value of either true
or false
, I'm using this to implement a dark mode feature and conditionally render styling on the page.
My toggle switch will parse a list of settings which get updated via the v-model
on the input and then committed to my store:
HTML
<v-list-tile avatar>
<v-list-tile-action>
<v-switch color="primary" v-model="settings.darkMode" @change="saveSetting('darkMode')"></v-switch>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dark mode</v-list-tile-title>
<v-list-tile-sub-title>Toggle app's dark mode.</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
My JS
data () {
return {
settings: {
darkMode: false,
dataSaver: false,
},
retrieveSettings: null,
isClearing: {
local: false,
sessions: false,
all: false
}
}
},
methods: {
/**
* Save settings to storage
*/
saveSetting() {
localStorage.setItem('my_settings',JSON.stringify(this.settings));
var beacon_settings = JSON.parse(localStorage.getItem('my_settings'));
this.retrieveSettings = beacon_settings
this.$store.commit('settings/add', {
darkMode: this.settings.darkMode,
dataSaver: this.settings.dataSaver
})
}
}
My store/settings.js file (Vuex)
export const state = () => ({
settings: []
})
export const mutations = {
add (state, settingsObject) {
state.settings.push(settingsObject)
}
}
This will successfully push the data that I can retrieve via a computed property in other pages of my website, however, every time I toggle the switch, it will push a new object into the settings
array rather than update the existing one, e.g:
[
{
darkMode: true,
dataSaver: false
},
{
darkMode: false,
dataSaver: false
}
]
Preferably I'd like to just update the existing object that was pushed, rather than push another one, I'm struggling with this bit and can't seem to figure this out. I might need to do something with $set
but not too sure.
Upvotes: 0
Views: 2824
Reputation: 1461
The easy way to this you can use the vuex-map-fields npm package. As you are using the list of items you have to use mapMultiRowFields. What you have to do simply generate the automated computed property & on update It will automatically set/update the value in store as well. Your code will be like
HTML:-
<v-list-tile avatar>
<v-list-tile-action>
<v-switch color="primary" v-model="settings.darkMode" @change="saveSetting('darkMode')"></v-switch>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title>Dark mode</v-list-tile-title>
<v-list-tile-sub-title>Toggle app's dark mode.</v-list-tile-sub-title>
</v-list-tile-content>
</v-list-tile>
Js:-
import { mapMultiRowFields } from 'vuex-map-fields';
export default {
data () {
return {
retrieveSettings: null,
isClearing: {
local: false,
sessions: false,
all: false
}
}
},
computed: {
...mapMultiRowFields(['settings']),
},
methods: {
/**
* Save settings to storage
*/
saveSetting() {
localStorage.setItem('my_settings',JSON.stringify(this.settings));
var beacon_settings = JSON.parse(localStorage.getItem('my_settings'));
this.retrieveSettings = beacon_settings
}
}
}
Upvotes: 0
Reputation: 11
The outcome is exactly what should be expected using:
state.settings.push(settingsObject)
I would recommend to go along with what was already commented and use an object instead of an array.
Use: settings: {}
insted of settings: []
to declare an object and change state.settings.push(settingsObject)
to state.settings = settingsObject
to override the existing object instead of adding a new object to an array.
See: https://vuex.vuejs.org/guide/mutations.html#mutations-follow-vue-s-reactivity-rules for more information and explanation.
Upvotes: 1