Создание раскрывающегося списка компонентов Vue с помощью Popper Js

Я продолжаю делать выпадающий компонент с vue и popperjs. Чтобы быть известным, я использую vuejs v.2.6.12 а также popperjs v.2.9.2 и вот код

      <template>
        <button type="button" @click="show = true">
            <slot />
            <portal v-if="show" to="dropdown">
                <div>
                    <div
                        style="position: fixed; top: 0; right: 0; left: 0; bottom: 0; z-index: 99998; background: black; opacity: .2"
                        @click="show = false"
                    />
                    <div
                        ref="dropdown"
                        style="position: absolute; z-index: 99999;"
                        @click.stop="show = autoClose ? false : true"
                    >
                        <slot name="dropdown" />
                    </div>
                </div>
            </portal>
        </button>
    </template>
    
    <script>
    import { createPopper } from "@popperjs/core";
    
    export default {
        props: {
            placement: {
                type: String,
                default: "bottom-end"
            },
            boundary: {
                type: String,
                default: "scrollParent"
            },
            autoClose: {
                type: Boolean,
                default: true
            }
        },
        data() {
            return {
                show: false
            };
        },
        watch: {
            show(show) {
                if (show) {
                    this.$nextTick(() => {
                        this.popper = createPopper(this.$el, this.$refs.dropdown, {
                            placement: this.placement,
                            modifiers: [
                                {
                                    name: "preventOverflow",
                                    options: {
                                        boundary: this.boundary
                                    }
                                }
                            ]
                        });
                    });
                } else if (this.popper) {
                    setTimeout(() => this.popper.destroy(), 100);
                }
            }
        },
        mounted() {
            document.addEventListener("keydown", e => {
                if (e.keyCode === 27) {
                    this.show = false;
                }
            });
        }
    };
    </script>

Когда я пытаюсь запустить код, я получаю сообщение об ошибке Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element. Я не знаю, почему у меня эта ошибка, думаю, я поставил ссылку this.$el и поппер this.$refs.dropdownв нужном месте.

Может ли кто-нибудь здесь помочь мне в решении этой проблемы?
Спасибо

1 ответ

Я создал сниппет, который работает без упомянутых ошибок.

  • ты использовал vue-portal: если он не импортируется глобально в вашем коде, вам необходимо импортировать его в SFC
  • ты должен создать <portal-target> где-нибудь, иначе this.$refs.dropdown не будет существовать, поскольку это содержимое по умолчанию portal.

Другие вопросы по тегам