效果:
封装模态框:
1.布局方面,有遮罩层,模态框水平居中,模态的头部左边是标题,右边是关闭按钮
2.用一个变量来控制模态框的显示与隐藏,使用v-model传递
3.内容部分使用插槽传递数据
4.底部的按钮组使用插槽显示对应信息
5.需要使用父传子开打开模态框,使用子传父来关闭等
父传子通信:
1.在父组件中的子组件标签上绑定一个自定义属性
2.子组件通过props接收数据,可以校验数据类型,设置默认值
3.接收到的数据可以直接使用
子传父通信(v-model):
1.在子组件标签上使用v-model绑定一个事件,如:v-model:事件名='数据',若不定义事件名,在使用时为modelValue代替
2.在子组件中定义一个方法,在该方法中调用emit方法,emit方法从setup函数的第二个参数中解构得出
3.emit方法有2个参数,第一个参数是自定义的事件,第二个参数是要传递的数据,如emit("update:modelValue", false);来改变父组件中v-model的值,也就是改变了父组件中的数据
父组件代码展示:
<template>
<button @click="isShow = true">打开对话框</button>
<model v-model="isShow">
<div>
<input type="text" placeholder="请输入账号" name="" id="" />
<br />
<input type="password" placeholder="请输入密码" name="" id="" />
</div>
</model>
</template>
<script>
import { reactive, ref, toRefs } from "vue";
import model from "./model.vue";
export default {
components: { model },
setup() {
let isShow = ref(false);
return {
isShow,
};
},
};
</script>
<style lang="less" scoped>
</style>
子组件代码展示:
<template>
<div
class="model"
:style="{
width: '300px',
height: '200px',
}"
v-show="modelValue"
>
<header>
<div>标题</div>
<div class="close" @click="close"></div>
</header>
<div class="body">
<slot></slot>
</div>
<footer>
<button @click="close">取消</button>
<button>确定</button>
</footer>
</div>
//遮罩层
<div class="xiaoe" v-show="modelValue"></div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
props: {
modelValue: {
type: Boolean,
},
},
setup(props, context) {
let name = ref("name");
let { emit } = context;
let close = () => {
emit("update:modelValue", false);
};
return {
name,
close,
};
},
});
</script>
<style lang="less" scoped>
.model {
z-index: 100;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
padding: 20px;
background: #eaeaea;
display: flex;
flex-direction: column;
justify-content: space-between;
.close::after {
content: "X";
}
.body {
flex: 1;
}
footer {
display: flex;
justify-content: flex-end;
}
header {
display: flex;
justify-content: space-between;
}
}
.xiaoe {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
</style>