1

In our frontend, we want to disable certain elements (i.e. buttons) depending on whether a user has "permissions" to trigger an action or not. To keep our code clean, we would like to do something like this:

<button reqPermission="edit">

This should call a JS method connecting to our permission service and Vue should only render the element / enable it if the request is truthy.

I don't have much clue of VueJS - what I would like to avoid though, is using something like v-if="...", since this would clutter our code. Any hints on how to implement such a "custom attribute" that influences the rendering of a component would be highly appreciated. What I found so far is https://forum.vuejs.org/t/how-to-conditionally-render-a-component/69687/6

4
  • A clean approach is to make it custom component. Commented May 7, 2021 at 11:38
  • The only way to not render an element/component is to use v-if. All the rest options (like v-show) will still render it in the dom. I could not understand why you want to avoid using v-if? Commented May 7, 2021 at 11:44
  • It sounds like your app is beyond the point of passing around props and needs a state store like Vuex Commented May 7, 2021 at 14:47
  • Did my answer solve your problem adequately or are you encountering issues? Please feel free to accept the answer or comment with further questions. Commented May 19, 2021 at 13:16

1 Answer 1

2

If you want to disable it based on a boolean you can do this inside the Vue template syntax:

<button :disabled="!userRights.edit">

If you want to prevent rendering instead of disabling the button, use v-if instead of :disabled.

If the boolean has to be loaded from a backend, I'd recommend using a vuex store action to fetch the user rights and conditional rendering based on the store state:

<template>
  <button :disabled="!isLoading && !userRights.edit">
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'buttonComponent',
  computed: {
    ...mapState('userModule', ['isLoading', 'userRights']),
  },
  mounted() {
    this.$store.dispatch('userModule/getRights')
  },
}
</script>

export default {
  namespaced: true,
  state: {
    isLoading: false,
    userRights: {
      edit: false,
      view: false,
    },
  },
  mutations: {
    updateIsLoading(state, isLoading) {
      state.isLoading = isLoading
    },
    updateUserRights(state, userRights) {
      state.userRights = userRights
    },
  },
  actions: {
    async getRights() {
      this.commit('userModule/updateIsLoading', true)

      const user = await getCurrentUserID()
      const rights = await getRightsByUser(user) // backend call

      this.commit('userModule/updateUserRights', rights)
      this.commit('userModule/updateIsLoading', false)
    },
  },
}
Sign up to request clarification or add additional context in comments.

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.