Théo Lavaux
Théo Lavaux

Reputation: 1454

Vue 3 Access to a DOM Element before mount

I'm creating a Vue <Link> component inside NuxtJS with the new composition API syntax. I would like to automatically set the color of my UiIcon when the root of the template has the disabled class.

I first thought to this approach, but then I realized that in the setup method, the DOM was not yet accessible. What could be another viable solution ?

PS: Managed to solve it using CSS stroke attribute because UiIcon is an SVG but I was curious if there as another solution utilizing the color pop already defined.

<template>
  <div ref="row" class="row">
    <UiIcon
      v-if="linkIcon"
      :type="linkIcon"
      :color="linkIconColor"
      class="icon"
    />
    <a
      class="link"
      :href="linkHref"
      :target="linkTarget"
      :rel="linkTarget === 'blank' ? 'noopener noreferrer' : null"
      @mouseover="linkActive = true"
      @mouseout="linkActive = false"
    >
      <slot></slot>
    </a>
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
  computed,
  ref,
  toRefs,
} from '@nuxtjs/composition-api';
import { Colors } from '~/helpers/styles';

export default defineComponent({
  name: 'Link',
  props: {
    href: {
      type: String,
      default: undefined,
    },
    target: {
      type: String as () => '_blank' | '_self' | '_parent' | '_top',
      default: '_self',
    },
    icon: {
      type: String,
      default: undefined,
    },
    iconColor: {
      type: String,
      default: undefined,
    },
    iconHoverColor: {
      type: String,
      default: undefined,
    },
  },
  setup(props) {
    const { href, target, icon, iconHoverColor } = toRefs(props);
    const linkActive = ref(false);
    const row = ref<HTMLDivElement | null>(null);

    const linkIconColor = computed(() => {
      const linkDisabled = row.value?.classList.contains('disabled');

      if (linkDisabled) {
        return Colors.DARK_GREY;
      }
      if (linkActive.value && iconHoverColor.value) {
        return props.iconHoverColor;
      }
      return props.iconColor;
    });

    return {
      linkHref: href,
      linkTarget: target,
      linkIcon: icon,
      linkIconColor,
      linkActive,
    };
  },
});
</script>

Upvotes: 3

Views: 5596

Answers (1)

Atif Zia
Atif Zia

Reputation: 793

According to Vue documentation beforeUpdate is a good place to access DOM element before Updated hook. However you can also use $nextTick to access DOM inside beforeMount.

 beforeMount() {
  this.$nextTick(function () {
    //code here
  })
}

Upvotes: 4

Related Questions