需求:整个项目的modal统一风格(本文以ant design of vue为例)
commonModal组件:
<template>
<a-modal :title="modalTitle"
centered
:maskClosable="false"
:visible="showModal"
:getContainer="() => parentDom"
@cancel="handleCancel">
<p>{{modalText}}</p>
<div slot="footer"
class="common-modal-footer">
<span v-if="hasCancelBtn"
@click="handleCancel">取消</span>
<span v-if="hasConfirmBtn"
@click="handleOk">确定</span>
</div>
</a-modal>
</template>
<script>
export default {
name: 'commonModal',
props: {
showModal: {
default: false,
type: Boolean
},
hasCancelBtn: {
default: false,
type: Boolean
},
hasConfirmBtn: {
default: false,
type: Boolean
},
modalTitle: {
default: '',
type: String
},
modalText: {
default: '',
type: String
},
parentDom: {
default: document.body,
type: HTMLElement
}
},
data () {
return {
}
},
created () {
},
methods: {
handleOk (e) {
this.$emit('confirm')
},
handleCancel (e) {
this.$emit('cancel')
}
}
}
</script>
<style lang="less">
.common-modal-footer {
display: -webkit-flex; /* Chrome 21+, Safari 6.1+, iOS Safari 7+, Opera 15/16 */
display: -moz-flex; /* Firefox 18+ */
display: -ms-flexbox; /* IE 10 */
display: flex; /* Chrome 29+, Firefox 22+, IE 11+, Opera 12.1/17/18, Android 4.4+ */
span {
-webkit-box-flex: 1;
-ms-flex: 1;
-webkit-flex: 1;
flex: 1;
font-size: 16px;
padding: 15px 0;
background-color: #fff;
height: inherit;
text-align: center;
cursor: pointer;
&:first-child {
border-right: 1px solid rgba(0, 0, 0, 0.09) !important;
border-radius: 0 0 0 4px;
color: #444 !important;
&:hover {
color: #1890ff !important;
}
}
&:last-child {
border-radius: 0 0 4px 0;
color: #1890ff !important;
&:hover {
color: #444 !important;
}
}
}
}
</style>
// modal的公共样式
.ant-modal {
font-family: Helvetica, Tahoma, Arial, STXihei, '华文细黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Heiti,
'黑体', sans-serif !important;
padding-bottom: 0 !important;
}
.ant-modal-close-icon:hover {
color: #1890ff !important;
transform: rotate(180deg) !important;
transition: 0.3s all !important;
}
.ant-modal-close-x {
font-size: 14px !important;
}
.ant-modal-title {
color: #222 !important;
text-align: center !important;
}
.ant-modal-body {
text-align: center !important;
p {
margin-bottom: 0 !important;
}
}
.ant-modal-footer {
padding: 0 !important;
}
在页面中使用:
1.背景为全屏的情况
<!-- html部分 -->
<common-modal :showModal="showModal1"
:modalTitle="modalTitle"
:modalText="modalText"
:hasCancelBtn="hasCancelBtn"
:hasConfirmBtn="hasConfirmBtn"
:parentDom="parentDom1"
@confirm="handleOk"
@cancel="handleCancel">
</common-modal>
// Js部分
const CommonModal = resolve => require(['@/views/common/commonModal'], resolve)
data () {
return {
showModal1: false,
modalTitle: '这是modal的标题',
modalText: '这是modal的文字',
hasCancelBtn: true,
hasConfirmBtn: true,
parentDom1: document.body
}
}
components: {
CommonModal
}
methods: {
showCommonModal() {
this.showModal1 = true
},
handleOk(e) {
this.showModal1 = false
},
handleCancel(e) {
this.showModal1 = false
}
}
2.背景为自定义元素的情况
<!-- html部分 -->
<div class="current-container"
ref="currentContainer">
<common-modal :showModal="showModal2"
:modalTitle="modalTitle"
:modalText="modalText"
:hasCancelBtn="hasCancelBtn"
:hasConfirmBtn="hasConfirmBtn"
:parentDom="parentDom2"
@confirm="handleOk"
@cancel="handleCancel">
</common-modal>
</div>
// Js部分
const CommonModal = resolve => require(['@/views/common/commonModal'], resolve)
data () {
return {
showModal2: false,
modalTitle: '这是modal的标题',
modalText: '这是modal的文字',
hasCancelBtn: true,
hasConfirmBtn: true,
parentDom2: document.body
}
},
components: {
CommonModal
}
methods: {
showSpecialModal() {
this.parentDom2 = this.$refs.currentContainer
this.showModal2 = true
},
handleOk(e) {
this.showModal2 = false
},
handleCancel(e) {
this.showModal2 = false
}
}
// css部分
<style lang="less">
@import '~@/assets/less/specialModal.less';
</style>
// specialModal.less文件
.current-container {
.ant-modal-mask {
background: rgba(0, 0, 0, 0.3) !important;
top: 97px !important;
left: 135px !important;
right: 15px !important;
bottom: 15px !important;
height: calc(100vh - 112px) !important;
border-radius: 4px !important;
}
.ant-modal-wrap {
top: 97px !important;
left: 135px !important;
}
}