vue3.2+ts實(shí)現(xiàn)在方法中可調(diào)用的擬態(tài)框彈窗(類el-MessageBox)
公司UI設(shè)計(jì)的擬態(tài)框彈窗跟Element Plus UI的布局不太一致。導(dǎo)致不能夠直接修改樣式得到想到樣式。直接上圖。

這個(gè)需求最主要的是要通過(guò)方法去調(diào)用。為了像el-messagebox使用那樣方便。能直接在方法中調(diào)用。但這也是難點(diǎn)。去查看了element源碼,一個(gè)套一個(gè)的方法 實(shí)在看不懂。因?yàn)関ue2和vue3的機(jī)制改動(dòng)了。vue2的引用方式不適用了。查找了n篇文章,最終在一篇中找到了一個(gè)關(guān)鍵點(diǎn),也可能是錯(cuò)誤的方式,但是能用。
import { createApp } from 'vue'
import MessageBoxVue from './MessageBox.vue' \\你寫(xiě)的擬態(tài)框樣式
export const MessageBox = (text: any) => {
return new Promise((resolve, reject) => {
const capp = createApp(MessageBoxVue, text)
const container = document.createElement('div')
const instance = capp.mount(container)
document.body.insertBefore(container, document.body.firstChild)//插入到body最前面,層級(jí)更高
instance.callback = (val: any) => {
if (val) {
resolve(val)
} else {
reject()
}
capp.unmount()//注銷
document.body.removeChild(container)//點(diǎn)擊后清除彈窗
}
instance.close = () => {
capp.unmount()
document.body.removeChild(container)
}
})
}//重點(diǎn)在這兒
//這邊相當(dāng)于把數(shù)據(jù)當(dāng)方法使了。我也不知道什么原理。在上面那邊就是能接收到回調(diào)。
const cancel = () => {
callback.value(false)
}
const confirm = () => {
callback.value(true)
}
const closeBox = () => {
close.value()
}
//拋出這兩個(gè)方法?反正這個(gè)方法不可或缺。
defineExpose({
callback,
close
})\\這一段是上面的那個(gè)messagebox
<template>
<div ref="MessageBox" class="message-box" :style="[messageBoxWrapperStyleStyle]">
<div class="message-box-icon">
<i class="iconfont" :style="`color:${iconColor}`" v-html="iconType"></i>
</div>
<div class="message-box-container">
<div class="message-box-title">{{ title }}</div>
<div v-if="isHtml" v-html="content"></div>
<p v-else class="message-box-content">{{ content }}</p>
<div class="message-box-btn">
<span v-if="isCancel" class="cancel" @click="cancel">{{ cancelVal }}</span>
<span v-if="isConfirm" class="confirm" @click="confirm">{{ confirmVal }}</span>
</div>
</div>
<i v-if="closeIcon" class="iconfont cencel-box" @click="closeBox"></i>
</div>
</template>
<script setup lang="ts">
import { computed, CSSProperties, ref } from 'vue'
const props = defineProps({
type: {
type: String,
default: 'warning'
},
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
isHtml: {
type: Boolean,
default: false
},
width: {
type: Number,
default: 416
},
isCancel: {
type: Boolean,
default: true
},
cancelVal: {
type: String,
default: '取消'
},
confirmVal: {
type: String,
default: '確定'
},
isConfirm: {
type: Boolean,
default: true
},
closeIcon: {
type: Boolean,
default: false
}
})
const callback = ref()
const close = ref()
const cw = document.documentElement.clientWidth
const ch = document.documentElement.clientHeight
// eslint-disable-next-line vue/return-in-computed-property
const iconType = computed(() => {
switch (props.type) {
case 'warning':
return ''
case 'info':
return ''
case 'error':
return ''
case 'success':
return ''
}
})
// eslint-disable-next-line vue/return-in-computed-property
const iconColor = computed(() => {
switch (props.type) {
case 'warning':
return '#FF7402'
case 'info':
return '#0C64EB'
case 'error':
return '#FF4D4F'
case 'success':
return '#36B23B'
}
})
const messageBoxWrapperStyleStyle = computed<CSSProperties>(() => {
return {
top: `${ch / 2 - 200 > 200 ? ch / 2 - 200 : 200}px`,
left: `${cw / 2 - props.width / 2}px`,
width: `${props.width}px`
}
})
const cancel = () => {
callback.value(false)
}
const confirm = () => {
callback.value(true)
}
const closeBox = () => {
close.value()
}
defineExpose({
callback,
close
})
</script>
<style lang="scss" scoped>
.cencel-box {
position: absolute;
top: 15px;
right: 20px;
cursor: pointer;
}
.message-box {
position: absolute;
border-radius: 5px;
z-index: 2001;
display: flex;
background: #ffffff;
padding: 20px 20px 20px 32px;
box-shadow: 0px 0px 20px 0px rgba(6, 0, 1, 0.1);
.message-box-icon {
margin-right: 12px;
line-height: 38px;
.iconfont {
font-size: 25px;
}
}
.message-box-container {
width: calc(100% - 25px);
.message-box-title {
font-size: 16px;
color: #333333;
line-height: 38px;
}
.message-box-content {
margin: 10px 0px 20px;
font-size: 14px;
min-height: 48px;
color: #999999;
line-height: 18px;
// letter-spacing: 0.5px;
}
}
.message-box-btn {
float: right;
.cancel {
height: 32px;
line-height: 30px;
display: inline-block;
text-align: center;
width: 90px;
box-sizing: border-box;
border: 1px solid #d9d9d9;
border-radius: 3px;
color: #333333;
cursor: pointer;
}
.cancel:hover {
color: #0c64eb;
border-color: #0c64eb;
}
.confirm {
height: 32px;
width: 90px;
display: inline-block;
text-align: center;
line-height: 32px;
margin-left: 10px;
background-color: #0c64eb;
border-radius: 3px;
color: #ffffff;
cursor: pointer;
}
.confirm:hover {
background-color: #2373eb;
}
}
}
</style>
引入全局后的調(diào)用
// 使用:
// 在main.ts全局引入,也可以按需引入這里展示全局引入
import {MessageBox} from 'base/src/components/MessageBox/index'
// 注冊(cè):
app.config.globalProperties.$messageBox = MessageBox
// 引用:
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const fn = ()=>{
proxy
.$messageBox({
//這邊就是傳你在MessageBox的props定義的父?jìng)髯拥臄?shù)據(jù)了
title: '是否確定編輯/刪除數(shù)據(jù)?',
content: '作業(yè)已經(jīng)發(fā)布,如果重新編輯/刪除,會(huì)清空所有學(xué)生 作業(yè)提交狀態(tài)請(qǐng)謹(jǐn)慎操作!'
})
.then(() => {
console.log(1234)
})
.catch(() => {
console.log(12345)
})
}到此這篇關(guān)于vue3.2+ts實(shí)現(xiàn)在方法中可調(diào)用的擬態(tài)框彈窗(類el-MessageBox)的文章就介紹到這了,更多相關(guān)vue3.2+ts實(shí)現(xiàn)擬態(tài)框彈窗內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中設(shè)置height:100%無(wú)效的問(wèn)題及解決方法
這篇文章主要介紹了vue中設(shè)置height 100%無(wú)效的問(wèn)題及解決方法,需要的朋友可以參考下2018-07-07
如何通過(guò)Vue3+Element?Plus自定義彈出框組件
這篇文章主要給大家介紹了關(guān)于如何通過(guò)Vue3+Element?Plus自定義彈出框組件的相關(guān)資料,彈窗是前端開(kāi)發(fā)中的一種常見(jiàn)需求,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-05-05
vue實(shí)現(xiàn)發(fā)送短信倒計(jì)時(shí)和重發(fā)短信功能的示例詳解
這篇文章主要給大家介紹了vue實(shí)現(xiàn)發(fā)送短信倒計(jì)時(shí)和重發(fā)短信功能的相關(guān)知識(shí),文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
vue實(shí)現(xiàn)登陸登出的實(shí)現(xiàn)示例
本篇文章主要介紹了vue實(shí)現(xiàn)登陸登出的實(shí)現(xiàn)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
vue3實(shí)現(xiàn)監(jiān)聽(tīng)store中state狀態(tài)變化的簡(jiǎn)單方法
這篇文章主要給大家介紹了關(guān)于vue3實(shí)現(xiàn)監(jiān)聽(tīng)store中state狀態(tài)變化的簡(jiǎn)單方法,store是一個(gè)狀態(tài)管理工具,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
vue數(shù)據(jù)push后不能響應(yīng)式更新的問(wèn)題
這篇文章主要介紹了vue數(shù)據(jù)push后不能響應(yīng)式更新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue利用sync語(yǔ)法糖實(shí)現(xiàn)modal彈框的項(xiàng)目實(shí)踐
本文主要介紹了vue利用sync語(yǔ)法糖實(shí)現(xiàn)modal彈框的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
vue+canvas實(shí)現(xiàn)移動(dòng)端手寫(xiě)簽名
這篇文章主要為大家詳細(xì)介紹了vue+canvas實(shí)現(xiàn)移動(dòng)端手寫(xiě)簽名,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
vue 解決mintui彈窗彈起來(lái),底部頁(yè)面滾動(dòng)bug問(wèn)題
這篇文章主要介紹了vue 解決mintui彈窗彈起來(lái),底部頁(yè)面滾動(dòng)bug問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11

