我有一个组件,我需要在屏幕上显示一些自定义模式。我不知道应该把这个对话框的内容放在哪里,所以我做了类似的事情:
<template>
<div class="ComponentItself">
<div v-show="false" ref="ModalContent">
Hello!
</div>
<button v-on:click="showModal">Show modal</button>
</div>
</template>
[...]
注意:我无法将
[ref=ModalContent]
的标记名称设置为template
,因为vue会将此标记保留为其他功能。
我的想法是当我点击&#34; show modal&#34;它打开创建了我用v-dialog
内容创建的另一个组件([ref=ModalContent]
)的实例(它应该被编译为支持嵌套的vue组件)。
import Dialog from './Dialog';
const DialogCtor = Vue.extend(Dialog);
const dialog = new DialogCtor({ propsData: {...} });
dialog['$slots'].default = [ this.$refs['templateNewFolder'].innerHTML ];
{something like document.body.appendChild(dialog.$el)}
这个另一个组件有一个插槽,可以接收要在其中显示的HTML内容。它只是不起作用。显示模式,但插槽内容为undefined
或未解析的HTML内容。
<div class="Dialog">
[...]
<slot></slot>
[...]
</div>
目前的结果如下:
我需要什么:
component
功能,但我无法识别或理解是否可以解决我的问题; .appendChild()
直接$slot.default
,但这是不可能的; 答案 0 :(得分:1)
在我看来,这可能是XY problem的情况。
可能发生的情况是您不需要手动填充$slot.default
,而是以更标准的方式使用您的Dialog
组件。由于在您的问题中没有关于后者的细节,该组件可能还需要一些重构来适应这种“标准方式”。
因此,更标准的方法是直接在父级模板中使用<custom-dialog>
组件,而不是使用您必须隐藏的占位符(您引用为ModalContent
的占位符)。这样,您在<custom-dialog>
内传递的任何HTML都会被输入您的Dialog
的{{1}}(设计好的广告位)。
这样您还可以省去手动实例化Dialog组件的麻烦。
然后,您可以切换<slot>
可见性(使用<custom-dialog>
或v-if
),甚至可以在代码中提及操作DOM中的位置;当v-show
是Vue实例时,您可以以$el
:this.$refs.ModalContent.$el
访问其DOM节点。
您还可以通过将ModalContent
方法委托给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>
,那么问题评论中的@ Sphinx linked answer是一种可接受的方法。请注意,那里接受的答案也有利于标准用法。在我看来,这也是@Sphinx在第二次评论中暗示的内容。