<div id="app">
<dialog-instance ref="dialog">
<div class="dialog-custom-content">this is the dialog content</div>
</dialog-instance>
<div class="demo-container">
<button @click="showDialog" class="demo-button">click me show dialog</button>
</div>
</div>
<script type="text/x-template" id="dialog">
<div class="dialog-container">
<div
:class="['dialog-mask', visible && 'fade-in', !showMask && 'hide-mask']"
@click="closeMask"
/>
<div
class="dialog-content"
@click.stop=""
>
<slot />
</div>
</div>
</script>
// dialog style
.dialog-mask {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.19);
opacity: 0;
visibility: hidden;
transition: all 0.3s;
}
.dialog-content {
visibility: hidden;
min-height: 1rem;
min-width: 1rem;
position: fixed;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0) scale(0.7);
transform-origin: center;
opacity: 0;
transition: all 0.3s;
}
.fade-in {
visibility: visible;
opacity: 1;
& + .dialog-content {
visibility: visible;
transform-origin: center;
transform: translate3d(-50%, -50%, 0) scale(1);
opacity: 1;
}
}
.hide-mask {
visibility: hidden;
}
// demo style
.demo-container {
padding: 100px 0;
}
.demo-button {
padding: 10px;
display: block;
margin: 0 auto;
&:hover {
background: #eee;
}
}
.dialog-custom-content {
padding: 52px;
background: #fff;
border-radius: 4px;
}
View Compiled
Vue.component('dialog-instance',{
template: "#dialog",
props: {
// 点击遮罩是否关闭
// click mask close
maskClose: {
type: Boolean,
default: true
},
// 是否展示遮罩层
// control mask display
showMask: {
type: Boolean,
default: true
},
disableScroll: {
type: Boolean,
default: false
},
callback: {
type: Function,
default: function () {}
}
},
data() {
return {
visible: false
};
},
mounted() {
const body = document.querySelector("body");
if (body.append) {
body.append(this.$el);
} else {
body.appendChild(this.$el);
}
},
methods: {
open() {
this._disableScroll();
this.visible = true;
},
close() {
this.visible = false;
document.documentElement.style.overflow = "";
this.callback && this.callback();
},
_disableScroll() {
if (this.disableScroll)
document.documentElement.style.overflow = "hidden";
},
closeMask() {
if (!this.maskClose) return;
this.close();
}
}
});
new Vue({
el: "#app",
methods: {
showDialog() {
this.$refs['dialog'].open();
}
}
});
This Pen doesn't use any external CSS resources.