文章详情

公司UI设计的拟态框弹窗跟Element Plus UI的布局不太一致。导致不能够直接修改样式得到想到样式。直接上图。

vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)

这个需求最主要的是要通过方法去调用。为了像el-messagebox使用那样方便。能直接在方法中调用。但这也是难点。去查看了element源码,一个套一个的方法 实在看不懂。因为vue2和vue3的机制改动了。vue2的引用方式不适用了。查找了n篇文章,最终在一篇中找到了一个关键点,也可能是错误的方式,但是能用。

import { createApp } from 'vue'
import MessageBoxVue from './MessageBox.vue' \\你写的拟态框样式
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最前面,层级更高
instance.callback = (val: any) => {
if (val) {
resolve(val)
} else {
reject()
}
capp.unmount()//注销
document.body.removeChild(container)//点击后清除弹窗
}
instance.close = () => {
capp.unmount()
document.body.removeChild(container)
}
})
}
//重点在这儿
//这边相当于把数据当方法使了。我也不知道什么原理。在上面那边就是能接收到回调。
const cancel = () => {
callback.value(false)
}
const confirm = () => {
callback.value(true)
}
const closeBox = () => {
close.value()
}
//抛出这两个方法?反正这个方法不可或缺。
defineExpose({
callback,
close
})
\\这一段是上面的那个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>

引入全局后的调用

// 使用:
// 在main.ts全局引入,也可以按需引入这里展示全局引入
import {MessageBox} from 'base/src/components/MessageBox/index'
// 注册:
app.config.globalProperties.$messageBox = MessageBox
// 引用:
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const fn = ()=>{
proxy
.$messageBox({
//这边就是传你在MessageBox的props定义的父传子的数据了
title: '是否确定编辑/删除数据?',
content: '作业已经发布,如果重新编辑/删除,会清空所有学生 作业提交状态请谨慎操作!'
})
.then(() => {
console.log(1234)
})
.catch(() => {
console.log(12345)
})
}

到此这篇关于vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)的文章就介绍到这了,更多相关vue3.2+ts实现拟态框弹窗内容请搜索码农网以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农网!

您可能感兴趣的文章:

  • 可能是全网vue v-model最详细讲解教程
  • Vue3中echarts无法缩放的问题及解决方案
  • Vue $nextTick 为什么能获取到最新Dom源码解析
  • Vue生命周期实例分析总结
  • Vue实现简单基础的图片裁剪功能
  • vue.config.js 的完整配置(超详细)
  • vue原生input输入框原理剖析
  • 详解Vue 的异常处理机制

版权:版权申明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 70068002@qq.com 举报,一经查实,本站将立刻删除。

转载请注明出处:https://www.stntk.com/2555.html

相关推荐
JS前端模拟Excel条件格式实现数据条效果
需求背景 最近业务中遇到一个有意思的需求,是要在现有的表格中实现类似 Excel 中的数据条的效果,在数据比较多的时候单纯看表格里的数字会比…
头像
前端开发 2024-05-26
933
js 实现汉字简体和繁体之间的互相转换
简体字 简体字(Simplified Chinese,简体中文),是中国大陆地区目前在用的字体,由官方公布的简体字,主要由传承字以及1950…
头像
前端开发 2024-05-26
713
如何使用nginx配置代理多个前端资源?
背景 两套不同的前端使用同一个后端服务,前端使用的Nginx代理的dist包 前端 vue+elementui 后端 Python+flas…
头像
前端开发 2024-05-26
582
jquery实现ul列表中点击li选择radio
如何利用jquery实现ul列表中点击li选择radio呢? 1、HTML代码 <ul class="list-group"> …
头像
前端开发 2024-05-26
1,133
vue3.2+ts实现在方法中可调用的拟态框弹窗(类el-MessageBox)
公司UI设计的拟态框弹窗跟Element Plus UI的布局不太一致。导致不能够直接修改样式得到想到样式。直接上图。 这个需求最主要的是要…
头像
前端开发 2024-05-26
1,139
前端如何实现网页变灰功能?
今天来从前端的角度看看网页置灰是如何实现的,以及相关使用技巧! 实现思路 先来看看一些主流网站是如何实现置灰的: BiliBili: 京东 …
头像
前端开发 2024-05-26
861
发表评论
暂无评论

还没有评论呢,快来抢沙发~

点击联系客服

在线时间:8:00-16:00

客服电话

400-888-8888

客服邮箱

70068002@qq.com

扫描二维码

关注微信公众号