Query Strings, Vue and Bootstrap Active Tab

Posted: 2018-08-19 12:55:35

In order to have the tabs and URL change as needed when the user lands on the page or clicks the tab I had to setup a few things.

First I setup the Vue.js router as seen here

Then my component will work out the rest.

Using BV

I have tabs and then I set those tabs as needed.

                <b-tabs v-model="activeTab">
                    <b-tab title="Settings" active >
                        <div class="mt-4 alert alert-info">
                            Manage related policies by clicking on the Tabs.

                            <ul>
                                <li>See Results</li>
                                <li>Add Policies</li>
                                <li>Update Policies</li>
                            </ul>
                        </div>
                    </b-tab>
                    <b-tab title="Quality Metrics">
                        <quality-metrics-report class="mt-4" v-if="this.$store.state.tabIndex == 1"></quality-metrics-report>
                    </b-tab>
                    <b-tab title="Travis File Report">
                        <travis-subscription-root class="mt-4"  v-if="this.$store.state.tabIndex == 2"></travis-subscription-root>
                    </b-tab>
                </b-tabs>

When I user clicks on the tabs the state changes since the activeTab is a computed property.

    computed: {
        activeTab: {
            get: function() {
                return this.$store.state.tabIndex;
            },
            set: function(newTab) {
                let tabs = {
                    tab:  _.findKey(this.tabs, function(o) {return o == newTab;})
                }
                this.$router.push({
                    query: tabs
                });
                console.log(this.$router.history.current);
                this.$store.commit('tabIndex', newTab);
            },
        },

Using lodash I can easily find my tab name from the value of the tabe we are looking at.

    data() {
        return {
            tabs: { travis_policy_results: 2, quality_metrics_report: 1 }
        }
    },

That takes care of the user clicking. I could store the state right in the component but I am doing this in vuex which should not matter here really.

Now when the user lands on the page my mounted method acts on the url:

    mounted() {
        if(this.$router.history.current['query']['tab']) {
            let tab = this.$router.history.current['query']['tab'];
            this.$store.commit('tabIndex', this.tabs[tab]);
        }
    },

That is it now the state changes on page land and on click.

I can also have it change as the user clicks on their Back button.

    methods: {
        changeTab() {
            let tab = this.$router.history.current['query']['tab'];
            this.$store.commit('tabIndex', this.tabs[tab]);
        }
    },
        mounted() {
        if(this.$router.history.current['query']['tab']) {
             this.changeTab();
        }
    },
    watch: {
        $route(to, from) {
            if (to.fullPath != from.fullPath) {
                this.changeTab();
            }
        }
    },

Tags:

vuejs laravel