Search code examples
vue.jsvuexbootstrap-vue

Store bootstrap toggle in store


Is there a way to store a toggled vue-bootstrap view in a vuex store?

    <div class="mb-5 mt-5">
        <button class="mr-2 button_class" v-b-toggle="'searchByName searchBySeason'">toggle</button>
    </div>
    
    <b-collapse id="searchByName" visible>
      // stuff
    </b-collapse>

    <b-collapse id="searchBySeason">
      // stuff
    </b-collapse>

I wanna store the state of the toggled element so it'll still be there after reloading the page.


Solution

  • You can bind a property to <b-collapse>'s v-model, which will be true or false depending on the collapses state.

    You can then for example use a computed property with a getter/setter to get and set your store state.

    <template> 
      <b-collapse v-model="isNameCollapseOpen" id="searchByName">
        // stuff
      </b-collapse>
    </template>
    
    <script>
    export default {
      computed: {
        isNameCollapseOpen: {
          get() {
            // Get state from store
            return this.$store.state.isNameCollapseOpen
          },
          set(isOpen) {
            // Update store using a mutation
            this.$store.commit('SET_NAME_COLLAPSE_STATE', isOpen)
          }
        }
      }
    }
    </script>
    

    Be aware that things saved in Vuex doesn't persist between page loads, meaning if you reload the page, the state is lost by default. However, there are plugins to persist store state, like vuex-persist or vuex-persistedstate.

    Example

    const store = new Vuex.Store({
      state: {
        isNameCollapseOpen: false
      },
      mutations: {
        SET_NAME_COLLAPSE_STATE(state, isVisible) {
          state.isNameCollapseOpen = isVisible
        }
      }
    })
    
    new Vue({
      el: "#app",
      store: store,
      computed: {
        isNameCollapseOpen: {
          get() {
            // Get state from store
            return this.$store.state.isNameCollapseOpen
          },
          set(isOpen) {
            // Update store using a mutation
            this.$store.commit('SET_NAME_COLLAPSE_STATE', isOpen)
          }
        }
      }
    });
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" />
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/[email protected]/dist/bootstrap-vue.min.css" />
    <script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.min.js"></script>
    
    <div id="app">
      <b-btn v-b-toggle.search-by-name>Toggle collapse</b-btn>
    
      <b-collapse v-model="isNameCollapseOpen" id="search-by-name">
        Some text
      </b-collapse>
      <hr /> Store state: {{ $store.state.isNameCollapseOpen }}
    </div>