封装API式弹窗组件

96 阅读1分钟

这里没有通过在template模板中调用弹窗组件,而是调用函数的形式来展示弹窗组件

<script setup>
import showMsg from '@/utils/message.jsx'

function openMsg() {
  showMsg('我的提示框', (close) => {
    close()
  })
}
</script>

<template>
  <div>
    <div class="btn" @click="openMsg">打开弹窗</div>
  </div>
</template>

<style lang="scss" scoped>
.btn {
  background-color: skyblue;
  width: fit-content;
  height: 40px;
  padding: 0 20px;
  line-height: 40px;
  border-radius: 8px;
  color: #fff;
  margin: 0 auto;
  cursor: pointer;
  user-select: none;
}
</style>

需要注意的是,这里使用了styils第三方库(css in js),来解决在jsx中完成对样式的编写

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

// 样式
const Popup = styled('div', {
    position: 'absolute',
    top: '0',
    left: '0',
    bottom: '0',
    right: '0',
    margin: 'auto',
    width: '300px',
    height: '150px',
    textAlign: 'center',
    backgroundColor: 'skyblue',
    borderRadius: '10px',
})

const Content = styled('div', {
    color: '#000',
    fontSize: '20px',
    marginTop: '30px',
})

const Confirm = styled('div', {
    width: '80px',
    height: '40px',
    fontWeight: '600',
    lineHeight: '40px',
    textAlign: 'center',
    backgroundColor: '#4160e7',
    margin: '35px auto 0',
    cursor: 'pointer',
    userSelect: 'none',
    color: '#fff',
    borderRadius: '10px',
})

// 弹窗组件
const MessageBox = {
    props: {
        msg: {
            type: String,
            required: true
        },
        close: {
            type: Function,
            required: true
        },
    },
    render(ctx) {
        const { $props } = ctx

        return <Popup>
            <Content>{$props.msg}</Content>
            <Confirm onClick={$props.close}>确定</Confirm>
        </Popup>
    },
}

// 方法
export default function showMsg(msg, onClick) {
    const div = document.createElement('div')
    document.body.appendChild(div)

    // 渲染组件到界面上
    const app = createApp(MessageBox, {
        msg,
        close: () => {
            onClick(() => {
                app.unmount()
                div.remove()
            })
        }

    })
    app.mount(div)
}