Bootstrap

vue3实现单文件命令式弹窗组件

所需依赖

yarn add @styils/vue

调用的页面

<template>
  <div class="home">
	<el-button type="primary" @click="handleMessage">提示</el-button>
  </div>
</template>

<script lang="ts" setup>
	import showMsg from '@/utils/showMsg';
	const handleMessage = () => {
		showMsg('命令式组件!', (done?: () => void) => {
			done && done();
		})
	}
</script>

utils/showMsg.js

import { createApp } from 'vue'
import { styled } from '@styils/vue'

const wrapperDiv = styled('div', {
	position: 'fixed',
	width: '100%',
	height: '100%',
	left: 0,
	right: 0,
	top: 0,
	bottom: 0,
	zIndex: 999,
	background: '#00000050',
	display: 'flex',
	justifyContent: 'center',
	alignItems: 'center',
})
const boxDiv = styled('div', {
	backgroundColor: '#ffffff',
	color: '#333',
	padding: '30px 30px',
	borderRadius: '10px',
	width: '300px',
	display: 'flex',
	flexDirection: 'column',
	justifyContent: 'center',
	alignItems: 'center',
})
	

const tipDiv = styled('div', {
	marginBottom: '20px'
})

const messageBox = {
	props: {
		message: {
			type: String,
			default: '',
			require: true
		}
	},
	render(ctx) {
		const { $props, $emit } = ctx
		return (<wrapperDiv>
			<boxDiv>
				<tipDiv>{$props.message}</tipDiv>
				<button click={$emit('onClick')}>关闭</button>
			</boxDiv>
		</wrapperDiv>)
	}
}

function showMsg(message, callBack) {
	const div = document.createElement('div')
	document.body.appendChild(div)
	const app = createApp(messageBox, {
		message,
		onClick() {
			if (!callBack) {
				app.unmount()
				div.remove()
			} else {
				callBack(() => {
					app.unmount()
					div.remove()
				})
			}
		}
	})
	app.mount(div)
}

export default showMsg
;