来,效果图
- 文件结构
首先,你在vue的项目里面,找个合适的位置创建一个文件夹,创建一个vue的文件以及一个js文件
代码如下:
myDialog.vue
<template>
<div class="my-dialog" v-if="visible">
<div class="my-dialog-wrap">
<div class="my-dialog-title">
<span>{{title}}</span>
<div v-if="showCloseBtn" @click="close" class="my-dialog-btn my-close-btn"></div>
</div>
<slot></slot>
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
props:{
visible: {
type: Boolean,
default: false
},
showCloseBtn: {
type: Boolean,
default: true
},
title: {
type: String,
default: ''
}
},
methods:{
close(){
this.$emit('closeDia', false);
}
}
}
</script>
<style scoped>
.my-dialog{
position: fixed;
top: 0;
left: 0;
z-index: 99999;
width: 100%;
height: 100%;
background-color: rgba(24, 24, 24, .6)
}
.my-dialog .my-dialog-wrap{
position: absolute;
display: inline-block;
padding: 20px;
left: 50%;
top: 20%;
transform: translateX(-50%);
min-height: 60px;
min-width: 200px;
border-radius: 4px;
background-color: #fff;
}
.my-dialog .my-dialog-wrap .my-dialog-title{
display: block;
margin-bottom: 16px;
height: 29px;
width: 100%;
line-height: 22px;
border-bottom: 1px solid #242424;
}
.my-dialog .my-dialog-wrap .footer{
display: flex;
flex-direction: row-reverse;
margin-top: 16px;
padding-top: 10px;
height: 30px;
border-top: 1px solid #242424;
}
.my-dialog .my-dialog-wrap .my-dialog-btn{
position: relative;
float: right;
height: 20px;
width: 20px;
}
.my-dialog .my-dialog-wrap .my-close-btn{
border: 1px solid #242424;
border-radius: 2px;
cursor: pointer;
user-select:none;
}
.my-dialog .my-dialog-wrap .my-close-btn::before{
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%) rotate(45deg);
height: 65%;
width: 2px;
background-color: #242424;
}
.my-dialog .my-dialog-wrap .my-close-btn::after{
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%) rotate(45deg);
height: 2px;
width: 65%;
background-color: #242424;
}
.my-dialog .my-dialog-wrap .my-close-btn:hover{
border-color: #3D8A0A;
}
.my-dialog .my-dialog-wrap .my-close-btn:active{
border-color: #242424;
background-color: #3D8A0A;
}
.my-dialog .my-dialog-wrap .my-close-btn:active::before{
background-color: #fff;
}
.my-dialog .my-dialog-wrap .my-close-btn:active::after{
background-color: #fff;
}
</style>
写对话框主要问题在于 对话框的关闭与显示,solt 插槽如何区分脚部和整体内容
1.首先是如何控制显示的问题
我们通过在props中定义一个visible,然后再父标签使用v-if来控制显示,那么问题来了,如何关闭呢?当时我第一个想法是直接让visible = false来解决,可是刚要下键的时候觉得不行,因为子组件是不允许这样更改props里面的值。解铃还需系铃人,通过一个$emit来传一个closeDia给父组件,然后组件监听这玩意,然后执行操作就好。父组件的操作如下
然后父组件把自己定义显示组件的变量改为false就好,上图就是this.diaEditPw = false。这样显示的问题就解决了!
2.其次是插槽的控制的问题
首先,建议去了解slot插槽是啥才再来看这部分(不看的话,这里也有个大概),建议百度,很多大佬写的非常不错
可能很多人尝试自己这样写过,但是发现“啦啦啦”并没显示在组件里面,所以就需要一个 slot 标签
slot标签的作用可以粗略的理解为把组件标签内的内容带了进来。那么这个问题解决了,但是我看到element 的dialog还能区分 footer的哦!这个是需要slot另一个属性,name!只要给 solt 一个 name 属性就可以解决
然后调用的组件
只要一句 slot="footer" 只要和name里面一样就行。可能有人会觉得,那个 class="footer" 是干嘛的!这个是给 name="footer"的 slot 加入一个 class名,这样的话,写在dia组件里面的 footer 样式就会生效!当然也可以选择不用这么麻烦特意加一个footer的插槽,可以选择直接加一个 div class为 footer的也行!
只不过我个人觉得,这样不是规范,当然也是完全没有问题的。
3.引入的问题
index.js
import myDialogComponent from './myDialog.vue'
//注册
const myDialog = {
install:(Vue)=>{
Vue.component('my-Dialog', myDialogComponent);
}
}
export default myDialog;
main.js
import myDialog from '@/components/myDialog';//引入的弹框
Vue.use(myDialog);
这样,一个简单的全局的dialog对话框就完成了。