Мне кажется, что это может быть проблемой XY .
Что, вероятно, случается, что вам не нужно вручную заполнять $slot.default
, но используйте ваш Dialog
компонент более стандартным способом.Поскольку в последнем вопросе есть немного подробностей о последнем, этому компоненту также может потребоваться некоторый рефакторинг, чтобы соответствовать этому «стандартному способу».
Так что более стандартным подходом было бы непосредственное использование компонента <custom-dialog>
вшаблон вашего родителя, вместо использования заполнителя (тот, на который вы ссылаетесь ModalContent
), который вы должны скрыть.Таким образом, какой бы HTML-код вы ни передавали в этом <custom-dialog>
, он будет подаваться в Dialog
<slot>
(разработанный слот слота).
Таким образом, вы также избавите себя от необходимости вручную создавать экземплярваш компонент Dialog.
Затем вы можете переключать свою <custom-dialog>
видимость (с помощью v-if
или v-show
) или даже манипулировать ее положением в DOM, как вы упоминаете в своем коде;вы можете получить доступ к его узлу DOM как $el
: this.$refs.ModalContent.$el
, когда ModalContent
является экземпляром Vue.
Вы также можете разложить метод showModal
, делегировав его компоненту Dialog
.
Пример кода:
Vue.component('modal-dialog', {
template: '#modal-dialog',
data() {
return {
modalShown: false,
};
},
methods: {
showModal() {
this.modalShown = true;
},
hideModal() {
this.modalShown = false;
},
},
});
new Vue({
el: '#app',
methods: {
showModal() {
this.$refs.ModalContent.showModal();
},
},
});
/*
https://sabe.io/tutorials/how-to-create-modal-popup-box
MIT License https://sabe.io/terms#Licensing
*/
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 1rem 1.5rem;
width: 24rem;
border-radius: 0.5rem;
}
.close-button {
float: right;
width: 1.5rem;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<modal-dialog ref="ModalContent">
Hello!
</modal-dialog>
<h1>Hello World</h1>
<button v-on:click="showModal">Show modal</button>
</div>
<template id="modal-dialog">
<div class="modal" :class="{'show-modal': modalShown}" @click="hideModal">
<div class="modal-content">
<span class="close-button" ref="closeButton" @click="hideModal">×</span>
<slot></slot>
</div>
</div>
</template>
Теперь, если вы действительно хотите поиграться с $slot
, связным ответом @ Sphinx inкомментарии к вопросу - приемлемый подход.Обратите внимание, что принятый ответ также способствует стандартному использованию.Мне кажется, что это также то, что @Sphinx подразумевает во втором комментарии.