I’m currently creating the view-options for a Calendar in Vue.
Basicaly, you should be able to switch if you want to see entries for specific users and holidays for specific states.
When done, the values should be committed to the Vuex-store, using a Save-button.
Now here’s the Problem:
Funnily enough, the values for the shown holidays automatically update within the store, whenever i change any of them, while all other parameters only update, when I save the options.
At the moment, the options look basicaly like this: (There is more Modal-Stuff around, but I think this should be enough to show the Problem)
<form @submit.prevent="saveOptions">
<div class="modal-body">
<div class="row mb-2">
<div class="col">
<div class="form-floating">
<!--Dropdown Color Selection, Does not Auto Update-->
<select class="form-select" aria-label="Farbauswahl" v-model="selectedColor">
<option value="1">Opt 1</option>
<option value="2">Opt 2</option>
<option value="3">Opt 3</option>
<option value="4">Opt 4</option>
</select>
<label>Farbauswahl</label>
</div>
</div>
<div class="row">
<!--Bootstrap-Dropdown Show-User Selection with switches, Does not Auto Update-->
<div class="dropdown col d-flex">
<button class="btn btn-primary dropdown-toggle col" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">Angezeigte Nutzer</button>
<ul class="dropdown-menu p-2 w-100" aria-labelledby="dropdownMenuButton1">
<li v-for="(user, id) in $store.state.allUsers">
<div class="form-check form-switch col">
<input class="form-check-input" type="checkbox" :id="id" :checked="checkShownUser(id)" v-model="shownUserIDs" :value="id">
<label class="form-check-label w-100 user-select-none" :for="id" @click.stop>({{ user.initials }}) - {{ user.preName }} {{ user.surName }}</label>
</div>
</li>
</ul>
</div>
<!--Bootstrap-Dropdown inside Dropdown, Show-Holiday Selection with switches, DOES Auto Update-->
<div class="dropdown col d-flex">
<button type="button" class="btn btn-primary dropdown-toggle w-100" data-bs-toggle="dropdown" aria-expanded="false">Angezeigte Feiertage</button>
<ul class="dropdown-menu">
<div v-for="(substates, state) in $STATES" class="dropend">
<button class="btn dropdown-toggle w-100" type="button" data-bs-toggle="dropdown" @click.stop>{{ state }}</button>
<ul class="dropdown-menu w-100">
<li v-for="substate in substates">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" :id=substate :checked="checkShownHoliday(state, substate)" :value="substate" v-model="showHolidaysForStates[state]">
<label class="form-check-label w-100 user-select-none" :for=substate @click.stop>{{ substate }}</label>
</div>
</li>
</ul>
</div>
</ul>
</div>
</div>
<div class="row">
<div class="form-group d-flex">
<input type="checkbox" class="form-check-input" name="showWeekdays" id="showWeekdays" v-model="showWeekdays">
<label class="form-check-label user-select-none" for="showWeekdays">Wochentage anzeigen</label>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<div class="btn-group">
<button class="btn btn-primary">Speichern</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close">Zurück</button>
</div>
</div>
</form>
The script for this Component looks like this:
export default {
name: 'OptionModal',
data() {
return {
selectedColor: 1,
selectedTheme: 1,
shownUserIDs: [],
showWeekdays: false,
showHolidaysForStates: {
DE: [],
CH: [],
AT: []
}
};
},
methods: {
//Saves the options to the store
saveOptions() {
this.$store.commit("saveOptions", {
shownUserIDs: this.shownUserIDs,
selectedColor: this.selectedColor,
selectedTheme: this.selectedTheme,
showWeekdays: this.showWeekdays,
showHolidaysForStates: this.showHolidaysForStates,
})
},
//Creates the ID for the user-selection
createCheckboxID(id) {
return "checkOptionUser" + id;
},
//Checks if the current user is to be shown
checkShownUser(id) {
return this.shownUserIDs.includes(Number(id));
},
//Checks if the selected holidays are to be shown
checkShownHoliday(state, substate) {
return this.showHolidaysForStates[state].includes(substate)
},
},
created() {
this.showWeekdays = this.$store.state.currentUser.showWeekdays;
this.shownUserIDs = this.$store.state.currentUser.shownUserIDs;
this.selectedColor = this.$store.state.currentUser.selectedColor;
this.selectedTheme = this.$store.state.currentUser.selectedTheme;
//This seems to create a two-way binding with the store, while the others do not
this.showHolidaysForStates = this.$store.state.currentUser.showHolidaysForStates;
}
}
The global STATES is defined like this:
const STATES = {
DE: ["NI", "BW", "BY", "BE", "BB", "HB", "HH", "HE", "MV", "NW", "RP", "SL", "SN", "ST", "SH", "TH"],
CH: ["AG", "AI", "AR", "BE", "BL", "BS", "FR", "GE", "GL", "GR", "JU", "LU", "NE", "NW", "OW", "SG", "SH", "SO", "SZ", "TG", "TI", "UR", "VD", "VS", "ZG", "ZH", "CH"],
AT: ["B", "K", "N", "O", "S", "ST", "T", "V", "W"],
};
app.config.globalProperties.$STATES = STATES;
And finally tho store looks something like this:
export default createStore({
state: {
currentUser: {
userID: 1,
role: "Gast",
shownUserIDs: [1, 2, 3, 4, 5, 6, 7],
selectedTheme: 1,
selectedColor: 1,
showWeekdays: true,
showHolidaysForStates: { DE: ["NI"], AT: [], CH: [] },
},
mutations: {
saveOptions(state, payload) {
state.currentUser.shownUserIDs = payload.shownUserIDs;
state.currentUser.selectedColor = payload.selectedColor;
state.currentUser.selectedTheme = payload.selectedTheme;
state.currentUser.showWeekdays = payload.showWeekdays;
state.currentUser.showHolidaysForStates = payload.showHolidaysForStates;
},
}
},
By now I could not find any real solution.
It does seem, that the allocation in the “created” method of the component, creates a binding, which directly influences the store, which is strange, since the other 4 allocations do not create this kind of behaviour.