您现在的位置是:网站首页> 编程资料编程资料

ElementPlus el-message-box样式错位问题及解决_vue.js_

2023-05-24 452人已围观

简介 ElementPlus el-message-box样式错位问题及解决_vue.js_

ElementPlus el-message-box样式错位

不知道从哪个版本开始发现,element-plus的message-box在有图标的时候,错位比较严重,f12跟官网的样式对比后发现,好家伙!原来position: absolute被覆盖了。

错位效果截图

ElementPlus官网代码截图

本地项目代码截图

可以看出在本地中el-message-box__status样式的position并未生效

解决方案

修改css样式

.el-message-box__status { position: absolute !important; }

完成效果截图

实现ElementPlus的MessageBox

ElementPlus 的 MessageBox 主要功能分析

  • 1.提供一个函数用来展示消息框,这个函数提供如标题、内容等配置参数
  • 2.消息框出现和消失时有动画
  • 3.使用 Promise 获取消息框的结果

基本思路

Vue 中动态显示一个组件,无非就是通过 h 函数创建 VNode,并且把这个 VNode 挂载在 DOM 树上。这里有两种挂载的方式:

createApp

在 main.js 中创建 Vue 实例用的就是这种方法,这也是 Vue3 中代替 Vue2 的 Vue.extend 的方法,简单使用案例如下:

const app = createApp(MessageBox, {     message: 'hello?' }) // 创建无父元素的文档对象,挂载到 DOM 中后直接调用 app.unmount() 移除 MessageBox // 和挂载到 div 的区别是 MessageBox 不会作为 div 的子元素 const frg = document.createDocumentFragment() // app.mount 返回组件实例 // 组件实例内包含 expose 出来的方法或者数据 const vm = app.mount(frg) document.body.appendChild(frg)

h + render

和 createApp 方法大同小异

const vn = h(MessageBox, {     message: 'vnode' }) render(vn, container) document.body.appendChild(container)

可以看到无论是 createApp 方法还是 h 方法,都可以在第二个参数中传入组件的 props,于是我们可以封装一个动态显示组件的函数,这个函数接受组件的 props。但是在封装函数之前,让我们先来实现

MessageBox 这个组件

MessageBox 组件实现

直接贴代码,讲下最关键的几点:

进入退出动态效果实现

设置一个 transition flag,初始时为 false,组件 mounted 后 flag 为 true。

全局遮罩层

一个 fixed 定位宽高为100%的 div。

剩下的主要看 script 部分

函数式组件

// 第一个参数是 props,第二个参数是 context,类似 setup 的参数 // 返回值为 VNode // 可以导出或者直接在组件内部使用 const ContentView = ({ type }) => {     switch (type) {         case (!type || 'confirm'):             return h('p', null, message)         case 'prompt':             return h('input', {                 class: 'messagebox-input',                 onInput: (e) => promptContent.value = e.target.value             })     } }

封装 MessageBox 显示函数

import { createApp } from 'vue' import MessageBoxCpn from './MessageBox.vue' const fields = ['confirm', 'prompt'] export default function MessageBox(options) {     return new Promise((resolve, reject) => {         const app = createApp(MessageBoxCpn, {             ...options,             onDestroy: () => {                 app.unmount()             },             onOK: (value) => {                 resolve(value)             },             onCancel: () => {                 reject()             }         })         const frg = document.createDocumentFragment()         app.mount(frg)         document.body.appendChild(frg)     }) } fields.forEach(field => {     MessageBox[field] = (options) => {         options.type = field         return MessageBox(options)     } })

通过组件的 props 传入回调,实现按钮点击事件的传递、MessageBox 关闭时取消挂载的操作。

另外可以通过 MessageBox.prompt 等静态方法直接调用对应 type 的 MessageBox,实现方式是在 MessageBox 上挂上对应的静态方法,并且覆盖 options 的 type 选项。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。 

-六神源码网