0

As my project is growing, I've noticed a lot of repetitions. I'm starting with the navigations buttons, as they can appear in multiple places (side menu, navbar).

I'd like to centralize them and let the component import them as needed. So I've tried creating this file to hold all my menu items:

// menuItems.js

export default {
    data() {
        return {
            items: [
                { title: 'Profile', icon: 'mdi-account-circle', reqAuth: true, hideOnAuth: false},
                { title: 'Dashboard', icon: 'mdi-view-dashboard', reqAuth: true, hideOnAuth: false },
                { title: 'Settings', icon: 'mdi-cog', reqAuth: true, hideOnAuth: false },
                { title: 'Signup', icon: 'mdi-account-circle-outline', reqAuth: false, hideOnAuth: true},
                { title: 'Login', icon: 'mdi-login', reqAuth: false, hideOnAuth: true  },
                { title: 'Logout', icon: 'mdi-logout', reqAuth: true, hideOnAuth: false},
            ]
        }
    },
    methods: {
        menuItems: function(authenticated) {
            if (!authenticated) {
                // Gets items that do and don't require Auth, except for ones that should hide on Auth
                return this.items.filter(o => o.reqAuth || !o.reqAuth && !o.hideOnAuth)
            }
            // Gets items that don't require Auth
            return this.items.filter(o => !o.reqAuth)
        }
    }
}

Buttons can require authentication to be visible, and they can also be hidden once authenticated (eg. The login button).

Now lets assume I have a vue component for my nav bar, how do I import in the method that returns the filtered items?

// NavBarComponent.vue

<template>
    <div>
        <v-btn v-for="(item, i) in menuItems(authenticated)">
            {{ item.title }}
        </v-btn>
    </div>

</template>

<script>
    export default {
        name: "NavBarComponent",
        data() {
            return {
                authenticated: true,
            }
        },
        methods: {

        }
    }
</script>

In this case, how do i make menuItems in the component reference the external file that will do the work of filtering?

2 Answers 2

1

You can create a mixin file and put your methods in that mixin and apply the mixin your component.

https://v2.vuejs.org/v2/guide/mixins.html

Your mixin would look like this:

// /mixins/menuItemsMixin.js
const menuItemsMixin= {
  data() {
        return {
            items: [
                { title: 'Profile', icon: 'mdi-account-circle', reqAuth: true, hideOnAuth: false},
                { title: 'Dashboard', icon: 'mdi-view-dashboard', reqAuth: true, hideOnAuth: false },
                { title: 'Settings', icon: 'mdi-cog', reqAuth: true, hideOnAuth: false },
                { title: 'Signup', icon: 'mdi-account-circle-outline', reqAuth: false, hideOnAuth: true},
                { title: 'Login', icon: 'mdi-login', reqAuth: false, hideOnAuth: true  },
                { title: 'Logout', icon: 'mdi-logout', reqAuth: true, hideOnAuth: false},
            ]
        }
    },
    methods: {
        menuItems: function(authenticated) {
            if (!authenticated) {
                // Gets items that do and don't require Auth, except for ones that should hide on Auth
                return this.items.filter(o => o.reqAuth || !o.reqAuth && !o.hideOnAuth)
            }
            // Gets items that don't require Auth
            return this.items.filter(o => !o.reqAuth)
        }
    }
};

export default menuItemsMixin

And in your component:

// NavBarComponent.vue


<script>
    import menuItemsMixin from './mixins/menuItemsMixin.js'
    export default {
        mixins:[menuItemsMixin]
    }
</script>


You can import this mixin in multiple components and you can also add more mixins in this component where the unique methods will be added.

Sign up to request clarification or add additional context in comments.

Comments

0

I ended up creating a javascript file:

// views.js

export const views = [
    {title: 'Dashboard'},
    {title: 'Profile'},
    {title: 'Login/Signup'},
]

then in my navbar component I imported it like so:

    import {mapGetters} from "vuex";
    import {views} from "../../common/views";

    export default {
        data: () => ({
            items: views
        }),

        computed: {
            ...mapGetters(['isAuthenticated',])
            menuItems: function (){
                if (this.isAuthenticated) {
                    // do this
                } else {
                    // do this
                }
            },
        }
    }

Then I did the same for the filtering function, but I could also just re-code it as needed if required in each component. I determined authentication state using Vuex's store, and retrieve it with mapgetters.

<componentA v-if='isAuthenticated'>
     <navItem v-for='item in menuItems'>
</componentA>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.