简体   繁体   中英

Why Popper throws error Popper: Invalid reference or popper argument provided" in vuejs

I have wrote component in vue.js 2.6 what uses Propper.js.

Component is -generic popover component for displaying things like filters and menus in an element over the page.

For passing data into Popover function I am using refs maybe this is case?

Console throws error and says.

Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.

<template>
  <div>
    <div ref="popcorn" aria-describedby="tooltip">
      <slot name="action" :toggle="toggle" :close="close"></slot>
    </div>

    <div ref="tooltip" role="tooltip" v-if="isOpen">
      <div :class="[ci-popover, `ci-popover--background-color-${variant}`,`ci-divider--padding-${padding}`]">
        <slot name="default" />
        {{placement}}
      </div>
    </div>
  </div>
</template>

<script lang="ts">
  import { Vue, Component, Prop, Emit } from "vue-property-decorator";
  import { oneOfOptions } from "../../helpers/PropertyValidators";
  import { CiPopoverBackgroundColor, ciPopoverBackgroundColorArray } from './popover-background-color';
  import { CiPopoverPlacement, ciPopoverPlacementArray } from './popover-placement';
  import { CiSpacing, CiSpacingArray } from '../component-spacing';
  import { createPopper, Instance, VirtualElement } from '@popperjs/core';

  @Component
  export default class CiPopover extends Vue {
    $refs!: {
      popcorn: Element,
      tooltip: HTMLElement
    }
    /*Props/*


    created() {
      this.onOpen();
    }
    beforeDestroy() {
      this.onClose();
    }

    public close(): void {
      console.log('close method');

      console.log(this.$refs.tooltip);
      console.log(typeof this.$refs.tooltip);
    }
    public toggle(): void {
      console.log('toggle method');
      this.isOpen = true;
      console.log(this.$refs.popcorn);
      console.log(typeof this.$refs.popcorn);

    }

    @Emit('open')
    onOpen() {
      console.log("emit:open")
    }
    @Emit('close')
    onClose() {
      console.log("emit:close");
    }
    popperInstance = null as Instance | null
    isOpen = false;

    mounted() {
      this.popperInstance = createPopper(this.$refs.popcorn , this.$refs.tooltip, {
        placement: 'top'
      });  
    }
  }
</script>

Question is how to solve this problem?

Because the tooltip element is not rendered and so you are referencing to nothing.

Your tooltip element looks like:

    <div ref="tooltip" role="tooltip" v-if="isOpen">
      <div :class="[ci-popover, `ci-popover--background-color-${variant}`,`ci-divider--padding-${padding}`]">
        <slot name="default" />
        {{placement}}
      </div>
    </div>

It depends on the state isOpen if it should be rendered and you start with false as value as seen in:

isOpen = false

On mounted, you createPopper right away but you did not open the tooltip yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM