#app
.modal.simple-modal(
:style="{display: visibility ? 'block' : 'none'}",
)
.modal-dialog.modal-dialog-scrollable(
ref="dialog",
:class="dialogClass",
)
.modal-content(
ref="content",
:style="contentStyle",
)
.modal-header.p-2
h4 Hello
span.close(
@click="doClose",
) ×
.modal-body
img(src="http://evereditor.com/1.jpg")
View Compiled
.simple-modal
background-color: rgba(0, 0, 0, 0.5)
.modal-content
padding 1em
.close
cursor pointer
.modal-dialog-resizable
&.ready
max-width unset !important
.modal-content
resize both
margin 0 auto
.modal-body
padding 1rem 0 0
img
max-width 100%
View Compiled
const RESIZED_SIZE = 'resized_width_key';
let sharedSize;
const modal = new Vue({
el: '#app',
props: {
size: {
type: String,
default: null,
validator: function(value) {
return ['sm', 'lg', 'xl'].indexOf(value) !== -1;
},
},
resizable: {
type: Boolean,
default: true,
},
backdrop: {
type: Boolean,
default: true,
},
},
computed: {
dialogClass() {
const classes = [];
if (this.size) {
classes.push(`modal-${this.size}`);
}
if (this.resizable) {
classes.push('modal-dialog-resizable');
}
if (this.resizedSize) {
classes.push('ready');
}
return classes.join(' ');
},
contentStyle() {
if (!this.resizable || !this.resizedSize) {
return null;
}
const {width, height} = this.resizedSize;
return {
width: `${width}px`,
height: `${height}px`,
};
},
},
data() {
return {
visibility: false,
resizedSize: null,
};
},
methods: {
async doOpen() {
this.visibility = true;
this.$emit('open');
if (this.resizable) {
const onResize = _.debounce(this.onEditorResize, 100);
const observer = this.observer = new MutationObserver(onResize);
observer.observe(this.$refs.content, {
attributes: true,
});
if (!this.resizedSize) {
if (sharedSize) {
this.resizedSize = sharedSize;
} else {
await this.$nextTick();
const width = this.$refs.dialog.clientWidth;
this.resizedSize = {width};
}
}
}
},
doClose() {
this.visibility = false;
this.$emit('close');
},
onEditorResize([{target}]) {
const width = target.clientWidth;
const height = target.clientHeight;
if (width < 320 || height < 160) {
return;
}
sharedSize = {width, height};
localStorage.setItem(RESIZED_SIZE, JSON.stringify(sharedSize));
},
},
mounted() {
const size = localStorage.getItem(RESIZED_SIZE);
if (size) {
this.resizedSize = JSON.parse(size);
}
},
beforeDestroy() {
if (this.observer) {
this.observer.disconnect();
this.observer = null;
}
},
});
modal.doOpen();