今天看到一个讲类似element-plus中message box功能的视频,就是下图这个玩意,觉得非常有意思,并且业务里也实在能用上,比如说消息弹窗,右键菜单,功能详情页等等,所以来练习一下
视频里的大佬直接抛弃了组件选择使用jsx来render渲染组件,jsx和tsx我实在不会,就忽略这一步. 今天封装的目标是:
1.使他成为一个函数,函数触发时弹出一个窗口,点击窗口中的按钮关闭
2.如果能够靠传字段等方式选择要不要这个关闭按钮就更好了
3.能够灵活的改变窗口中的内容, 不仅限于简单的提示,能够装一个复杂的页面更好
-----------------------------------------------------------------分割线----------------------------------------------------------------------
首先开局第一步肯定是要创建一个基础的装弹窗的容器组件,如下图
一个蒙层效果,里面有一个小圆圈作为我们的关闭按钮,接下来要做的事就是,定义一个方法,这个方法在被调用时创建一个div元素并把元素加到body里,然后createApp创建一个根节点,.mount挂载上去并渲染出来.
上面的Biupage就是我们创建的容器组件,createApp第一个参数是需要挂载的组件,第二个参数是往这个组件中传入的属性和方法的集合对象,需要在组件中调用这些传入的属性时通过defineProps接收,这和父子组件传值差不多,我觉得需要注意的是关闭方法的传入.
这是调用弹窗函数时传入的值,其中TestView是一个组件,第二个参数以我的理解像是给一个BiuPage组件操作showBiu方法中属性的通道,具体我就直接图上标注了
文笔逻辑有限,实在看不懂可以问我, 总之在BiuPage组件中触发传入的OnClick事件就会把app卸载,把div删除,那我们的弹出层自然就不存在了,达到了关闭的效果
关闭页面解决了,如何向弹窗中发送我想要的页面, 这里我惊喜的发现,createApp第二个参数对象中的属性也可以包括组件
我们先简单创建一个小组件
就是一行字,然后在调用showBiu方法时把这个组件传入,进而createApp时传进Biupage页面
在BiuPage组件中使用时直接注册使用就可以了
最后出来的效果:
最后把代码贴一下
弹窗函数文件BiuCom.ts
import BiuPage from "@/components/BiuPage.vue";
import { createApp } from "vue";
export function showBiu(components:any,OnClick:Function){
const div = document.createElement('div')
document.body.appendChild(div)
/* const close=()=>{
app.unmount()
div.remove()
} */
const app = createApp(BiuPage,{
components
,
OnClick(){
OnClick(()=>{
app.unmount()
div.remove()
})
}
})
app.mount(div)
}
弹窗组件BiuPage.vue
<template>
<div class="father">
<div class="item">
<div class="closeBtn" @click="isClose">X</div>
<components></components>
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps({
OnClick:{
type:Function,
default:()=>{}
},
components:{
}
})
const isClose = ()=>{
props.OnClick()
}
</script>
<style lang="less" scoped>
.father{
width: 100%;
height: 100%;
position: absolute;
background: rgba(0,0,0,0.3);
.item{
background: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
.closeBtn{
background: gray;
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
top: 10px;
right: 10px;
}
}
}
</style>
试验时传入的简单页面TestView.vue
<template>
<h1>试验页面</h1>
</template>
问题总结:
1.可以说对createApp毫无理解,只能粗浅的使用
2.还没来得及深入去做,实际传入的组件可能会出现哪些问题呢?尝试之后或许会再续写本篇
3.这样做无论是控制关闭按钮的出现, 还是需要根据点击位置设置弹出框的位置, 都需要传参,需要灵活控制的选项越多,需要传的参数就越多. 这表明还需要大量的优化
4.创建dom,加入dom等对dom的操作会不会降低运行效率,有没有另外可行的方法或者优化方案