1、在conpmonents新建一个Modal.vue
2、在main.js注册成全局组件
// 全局可用的组件
import Modal from './components/Modal'
Vue.component('lx-modal', Modal)
3、在app.vue中使用组件
<div v-if="modalFlag">
<lx-modal></lx-modal>
</div>
4、编写Modal的代码逻辑
<template>
<div class="lx-modal" v-if="value">
<div class="lx-modal-bg"></div>
<div class="lx-modal-main" :style="{ width: width + 'px', top: top + 'px' }">
<i class="iconfont icon-guanbi-close" @click="close"></i>
<div class="lx-modal-main-header">
<slot name="header">{{ title ? title : '我是header' }}</slot>
</div>
<div class="lx-modal-main-content" :style="{ height: height + 'px' }">
<slot>我是content</slot>
</div>
<div class="lx-modal-main-footer">
<slot name="footer">
<div style="display: flex;flex-direction: row-reverse;">
<lx-button type="info" @click="save">确认</lx-button>
<lx-button @click="cancel">取消</lx-button>
</div>
</slot>
</div>
</div>
</div>
</template>
<script>
export default {
// eslint-disable-next-line vue/multi-word-component-names
name: 'Modal',
props: {
value:Boolean,
title: String,
width: String,
height: String,
top: String
},
data() {
return {
modal: true
}
},
methods: {
close() {
this.$emit('input', false)
},
cancel() {
this.$emit('on-cancel')
},
save() {
this.$emit('on-ok')
}
}
}
</script>
<style scoped>
@import url('../assets/icon/iconfont.css');
</style>
<style scoped lang="less">
.lx-modal {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1000;
}
.lx-modal-bg {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1000;
background-color: rgba(55,55,55,.6);
}
.lx-modal-main {
position: relative;
top: 100px;
width: 520px;
margin: 0 auto;
background-color: #fff;
z-index: 1001;
border-radius: 10px;
overflow: auto;
}
.iconfont {
font-size: 22px;
position: absolute;
top: 10px;
right: 10px;
}
.lx-modal-main-header {
padding: 14px 20px;
border-bottom: 1px solid #e8eaec;
font-weight: 500;
}
.lx-modal-main-content {
padding: 14px 20px;
border-bottom: 1px solid #e8eaec;
height: 200px;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
}
.lx-modal-main-footer {
padding: 14px 20px;
}
@media (max-width: 800px) {
.lx-modal-main {
width: auto !important;
}
}
</style>
在modal.vue中,我们在props中接受四个参数,title:标题,width:宽度, height:高度,top:距离顶部的高度,不传则是默认的值;并提供了两个具名插槽,header和footer,以及一个默认插槽slot显示里面的内容;并添加了三个自定义事件控制modal的显示和隐藏;v-if默认展示组件
注意一下:关于字体图标使用和用到的button组件、message提示组件可以看我之前发的封装button组件和message组件那个作品。message提示组件讲到了字体的引用以及封装,这几个自己封装的组件一起连着使用了
message组件及字体引入:https://blog.csdn.net/qq_55491577/article/details/136044309?spm=1001.2014.3001.5502
button组件 :
https://blog.csdn.net/qq_55491577/article/details/136029304?spm=1001.2014.3001.5502
5、来到App.vue
传递一些需要的参数,宽高就用默认的 代码如下:
<template>
<div id="#app">
<div v-if="modalFlag">
<lx-modal v-model="modalFlag" @on-cancel="cancel" @on-ok="ok" :title="title" top="50">
<template #header>
<div>
<h3>我是标题</h3>
</div>
</template>
<p>Content of dialog</p>
<p>Content of dialog</p>
<p>Content of dialog</p>
<p>Content of dialog</p>
<p>Content of dialog</p>
</lx-modal>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// modal是否显示
modalFlag: false,
// 标题
title: '我是标题'
}
},
methods:{
cancel() {
this.modalFlag = false
this.$Message.warning('取消成功')
},
ok() {
this.$Message.loading('正在保存')
this.$api.get('http://127.0.0.1:4000/api/list').then(res => {
if(res.status >= 200) {
this.$Message.success('保存成功')
this.modalFlag = false
}
})
}
}
}
</script>
在上面使用了header那个具名插槽 和默认插槽 更改了插槽中原本的内容:关于插槽的知识点
效果如下:
点击打开modal那个按钮弹出对话框
点击右上角的xx, 取消、确定都会把对话框隐藏,并使用message组件提示用户 ,可以再这三个事件写自己的逻辑,比如点击确定发起请求等;