vue3、ts 使用render函数,实现js调用、渲染组件,例:可实现全局通过js调用弹窗,request未登录拦截并弹窗显示登录等
vue3、ts 实现js调用、渲染组件,例:可实现全局通过js调用弹窗,request未登录拦截并弹窗显示登录等
·
1、首先创建一个普通的弹窗组件,放到页面中测试下是否能实现组件加载完毕后弹窗
注意: 用 transition 组件的时候,如果子元素做不同的动画,enter-active 和 leave-active 的动画时长需要与子元素动画时长最长的时间相等,不然会比较短会提前结束子元素动画,过长会导致子元素动画做完之后,蒙版产生遮挡
<script setup lang="ts">
import { onMounted, ref } from "vue";
const show = ref<boolean>(false);
const props = defineProps<{
removeNode: Function;
}>();
onMounted(() => {
// 页面挂在后开始做动画
show.value = true;
});
const close = () => {
if (show.value) {
//加这层判断主要为了防止用户频繁点击蒙版
//动画结束后关闭弹窗
show.value = false;
setTimeout(() => {
// 动画结束后移除元素
props.removeNode();
}, 500);
}
};
</script>
<template>
<div class="">
<transition name="pop">
<div class="pop-wrap" v-if="show">
<div class="mask" @click="close"></div>
<div class="pop-content">
<div class="title">弹窗组件</div>
<div class="content">
<slot></slot>
</div>
</div>
</div>
</transition>
</div>
</template>
<style scoped>
.pop-wrap {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.mask {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
transition: all 0.5s;
}
.pop-enter-active,
.pop-leave-active {
/* 时长需要与各个子元素(maske、pop-content)动画时长最长的相等 */
transition: all 0.5s;
}
.pop-enter-from .mask,
.pop-leave-to .mask {
opacity: 0;
}
.pop-enter-to .mask,
.pop-leave-from .mask {
opacity: 1;
}
.pop-enter-from .pop-content,
.pop-leave-to .pop-content {
opacity: 0;
transform: translate(-50%, -70%);
}
.pop-enter-to .pop-content,
.pop-leave-from .pop-content {
opacity: 1;
transform: translate(-50%, -50%);
}
.pop-content {
background: #fff;
border-radius: 10px;
width: 50%;
height: 40%;
padding: 10px;
position: absolute;
left: 50%;
top: 50%;
transition: all 0.5s;
transform: translate(-50%, -50%);
}
.title {
height: 50px;
font-size: 20px;
color: #333;
font-weight: bold;
line-height: 50px;
border-bottom: 1px solid #999;
}
</style>
2.在popup同级目录下创建一个index.ts 去渲染component
import { createApp, h } from "vue"
import Popup from './popup.vue'
export default function popup(vnNode: any) {
const parentNode = document.createElement('div')
const popupInstance = createApp({
render() {
return h(
Popup,
{
//popup的属性
removeNode: () => {
// 销毁弹窗组件
document.body.removeChild(parentNode)
}
},
// children
[
h(vnNode)
]
)
}
})
document.body.appendChild(parentNode)
popupInstance.mount(parentNode)
}
3.调用
<script setup lang="ts">
import createPopup from "./components/popup";
import PopupContent from './components/popConnt.vue'// 放入插槽的弹窗内容
const createComponent = ()=>{
createPopup(PopupContent)
}
</script>
<template>
<button @click="createComponent">创建组件</button>
</template>
更多推荐
已为社区贡献1条内容
所有评论(0)