2

I'm new to vue.js and I've encountered a problem that I can't fix. In my SelectField.vue component I have written the following method:

getModalBodyElement() {
      return document.querySelector('.modal-body') as HTMLElement;
    },

I want to use this to customise my modal body when a multiselect field opens and the body becomes scrollable:

onDropdownOpen() {
      nextTick(() => {
      const modalBodyElement = this.getModalBodyElement();
      // No idea why $el is not defined Multiselect extends Vue
      const dropdownElement = (this.$refs.multiselect as Multiselect).$el as HTMLElement;

      if (!modalBodyElement || !dropdownElement) return;

      const modalRect = modalBodyElement.getBoundingClientRect();
      const dropdownRect = dropdownElement.getBoundingClientRect();
      const extraHeight = dropdownRect.bottom + dropdownRect.height * Math.min(this.options.length, 5);

       console.log("element", modalBodyElement)
      if (extraHeight > modalRect.bottom) {
        this.originalModalHeight = modalBodyElement.offsetHeight;
        const newHeight = this.originalModalHeight + (extraHeight - modalRect.bottom);
        modalBodyElement.style.height = `${newHeight}px`;
        this.heightAdjusted = true;
      }
      });
    },

When I display the element in the console.log, it is also displayed. However, I cannot manipulate this element. In other words, this does not work: modalBodyElement.style.height

My work around was that I use a store which stores the ref from the body

<template>
  <section class="modal-body" ref="modalBodyRef">
    <slot name="body">My body is empty :(</slot>
  </section>
</template>
export default defineComponent({
  name: 'ModalBody',
  setup() {
    const modalBodyRef = ref<HTMLElement | null>(null);
    const modalStore = useModalStore();

    onMounted(() => {
      if (modalBodyRef.value) {
        modalStore.setModalBodyRef(modalBodyRef.value);
      }
    });

    return {
      modalBodyRef,
    };
  },
});

I now use this store instead of the querySelector. With some modals it works very well and with others it doesn't work. Here the element is displayed in the console again but I cannot manipulate it. I don't know what the problem is and hope you have an idea and can help me.

I have tried to solve my problem with the ref attribute by saving it in the store. Actually, every modal should now be able to use this ref to correctly adjust the height of the body. However, it works for some modals and not for others.

7
  • 5
    Use refs instead of querying the DOM Commented Jun 19, 2024 at 7:04
  • 4
    in general, if you use DOM methods (like .querySelector et al) in vue, you're no using vue correctly Commented Jun 19, 2024 at 7:04
  • @JaromandaX @Phil Hi..I didn't write the code, a colleague did. I'm just trying to fix the problem :) I have moved away from the queryselector and use a ref ref="modalBodyRef" for my modal body. Why is it that this now works with some of my modals and not with others? They all access this ref in my store. Commented Jun 19, 2024 at 7:18
  • vue itself has mechanisms to give you access to DOM. use them instead of writing vanilla js. vuejs.org/guide/essentials/template-refs.html Commented Jun 19, 2024 at 7:18
  • 1
    @michael.brilz It is possible you can do it using vuex or pinia, or any other state management system, you can share it and save it like any other data for later use. But, I think you are solving the problem wrong. I think you have to reconsider what you want, and what is the best way of doing it. There, if you check those, and using and saving ref values are optimum, do it ! Commented Jun 19, 2024 at 7:40

0

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.