Change menu items in MyLayout after user login



  • In MyLayout.vue I use EssentialLink component to manage some menu items.

    In the EssentialLink component I have create a new property “visible” to visualize or not the items.

    <template>
      <q-item
        clickable
        :to="to"
        v-if="visible"
      >
       ......
        icon: {
          type: String,
          default: ''
        },
          visible: {
          type: Boolean,
          default: true
        }
    

    In the login.vue page I should change the “visible” property of some of the Essentiallink elements when the user logs in, to disable or enable some features.

    Is it possible to access the MainLayout.vue array where the elements used by Essentiallink are stored from the login.vue page or call a method present in the MainLayout.vue ?

    Thank you very much.



  • @happymax

    Sure you can do that. In my apps I do this with a combination of vuex and computed properties. Where vuex is containing the state if you are authenticated or not. And a computed property in the EssentialLink component that maps to the vuex authenticated state with a vuex getter.

    //EssentialLink component
    <template>
        <q-item v-if="authenticated">
            ...
        </q-item>
    </template>
    
    <script>
    export default {
        name: "EssentialLink",
        computed: {
            authenticated () {
                return this.$store.getters.isAuthenticated
            }
    }
           
    };
    </script>
    
    // Vuex store getter & state
    state: {
       authenticated: false,            
     },
    getters: { 
       isAuthenticated (state) {
          return state.authenticated
       },
    


  • @dobbel

    Thanks for the answer and for your interesting solution.
    Is possibile to pass the item processed to the computed method ?



  • @happymax

    yes you can see this previous thread ( second post) :
    https://forum.quasar-framework.org/topic/6927/vuex-getter-undefined/2



  • @dobbel

    Sorry for the delay.

    I meant the ability to pass the essentiallink item to the computed method “authenticated”. Is possible ?



  • @happymax

    eum why would you want that? It is considered bad practice to send UI components to a state manager ( vuex store ).



  • @dobbel

    My goal is to have the ability to check if I must visualize an item menu depending on the user rigths.

    For example, if in the EssentialLink array if I add those items how can conditionally hide the first item if the user rights do not allow you to perform the function “Customers” ?

      this.essentialLinks.push({
              title  : 'Customers',
              caption: 'Customers list',
              icon   : 'person',
              to     : '/customers',
              visible: true
       })
      this.essentialLinks.push({
              title  : 'New Order',
              caption: 'Inserrt a new order',
              icon   : 'description',
              to     : '/order'
       })


  • @happymax

    My idea is that the authentication state and access level of the currentUser is stored in Vuex (‘as single source of truth)’ .

    Your essentialLinks component would then contain logic to show itself or not depending on the user rights of the current user ( stored in vuex ).

    Here in this code block the EssentialLink component will only display itself if the user is authenticated and hasAccess depending on for example ‘route’ :

    So instead of passing an entire Vue component you only pass the ‘to’ value.( the route)

    //EssentialLink component
    <template>
        <q-item v-if="authenticated && hasAccess">
            ...
        </q-item>
    </template>
    
    <script>
    //Eeesential link component
    export default {
        name: "EssentialLink",
        computed: {
            authenticated () {
                return this.$store.getters.isAuthenticated
            },
            hasAccess () {
                return this.$store.getters.hasAccess(this.to)
            }
    }
           
    };
    </script>
    

    the store with the hasAccess getter( this is a getter a with parameter, using function currying):

    // the store
    const getters = {
       hasAccess : state => route => {
          if(myUserRightsCheck(state.user, route)){
             return true
          } else {  return false }
       }
    }
    

    This way it will never show an EssentialLink component if a user has no access. And when the user does get access at runtime to a certain route, because you use a computed properties the EssentialLink will appear reactively.


Log in to reply