最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ElementPlus el-message-box樣式錯位問題及解決

 更新時間:2022年09月02日 11:20:53   作者:小狼子丶  
這篇文章主要介紹了ElementPlus el-message-box樣式錯位問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

ElementPlus el-message-box樣式錯位

不知道從哪個版本開始發(fā)現(xiàn),element-plus的message-box在有圖標的時候,錯位比較嚴重,f12跟官網(wǎng)的樣式對比后發(fā)現(xiàn),好家伙!原來position: absolute被覆蓋了。

錯位效果截圖

ElementPlus官網(wǎng)代碼截圖

本地項目代碼截圖

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

解決方案

修改css樣式

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

完成效果截圖

實現(xiàn)ElementPlus的MessageBox

ElementPlus 的 MessageBox 主要功能分析

  • 1.提供一個函數(shù)用來展示消息框,這個函數(shù)提供如標題、內(nèi)容等配置參數(shù)
  • 2.消息框出現(xiàn)和消失時有動畫
  • 3.使用 Promise 獲取消息框的結(jié)果

基本思路

Vue 中動態(tài)顯示一個組件,無非就是通過 h 函數(shù)創(chuàng)建 VNode,并且把這個 VNode 掛載在 DOM 樹上。這里有兩種掛載的方式:

createApp

在 main.js 中創(chuàng)建 Vue 實例用的就是這種方法,這也是 Vue3 中代替 Vue2 的 Vue.extend 的方法,簡單使用案例如下:

const app = createApp(MessageBox, {
?? ?message: 'hello?'
})
// 創(chuàng)建無父元素的文檔對象,掛載到 DOM 中后直接調(diào)用 app.unmount() 移除 MessageBox
// 和掛載到 div 的區(qū)別是 MessageBox 不會作為 div 的子元素
const frg = document.createDocumentFragment()
// app.mount 返回組件實例
// 組件實例內(nèi)包含 expose 出來的方法或者數(shù)據(jù)
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 方法,都可以在第二個參數(shù)中傳入組件的 props,于是我們可以封裝一個動態(tài)顯示組件的函數(shù),這個函數(shù)接受組件的 props。但是在封裝函數(shù)之前,讓我們先來實現(xiàn)

MessageBox 這個組件

MessageBox 組件實現(xiàn)

直接貼代碼,講下最關(guān)鍵的幾點:

進入退出動態(tài)效果實現(xiàn)

設(shè)置一個 transition flag,初始時為 false,組件 mounted 后 flag 為 true。

全局遮罩層

一個 fixed 定位寬高為100%的 div。

剩下的主要看 script 部分

<template>
? ? <transition name="messagebox-fade" @after-leave="onDestroy">
? ? ? ? <div @click="setVisiable(false)" v-show="visiable"
? ? ? ? ? ? class="z-50 flex items-center justify-center fixed top-0 left-0 w-full h-full bg-dark-50/50">
? ? ? ? ? ? <div @click.stop class="transform -translate-y-1/2 p-2 rounded min-w-3/7 bg-white">
? ? ? ? ? ? ? ? <p class="text-sm text-gray-600 font-light"> {{ title }}</p>
? ? ? ? ? ? ? ? <p class="my-4 text-lg">
? ? ? ? ? ? ? ? ? ? <content-view :type="type"></content-view>
? ? ? ? ? ? ? ? </p>
? ? ? ? ? ? ? ? <div class="w-full flex justify-end items-center">
? ? ? ? ? ? ? ? ? ? <button @click="okBtnClicked" class="btn btn-primary"> {{ ok }}</button>
? ? ? ? ? ? ? ? ? ? <button @click="cancelBtnClicked" v-if="cancel" class="ml-2 btn btn-danger"> {{ cancel }}</button>
? ? ? ? ? ? ? ? </div>
? ? ? ? ? ? </div>
? ? ? ? </div>
? ? </transition>
</template>
<script setup>
import { ref, onMounted, h } from 'vue'
const { onOK, onCancel, message } = defineProps({
? ? title: {
? ? ? ? type: String,
? ? ? ? default: '提示'
? ? },
? ? message: {
? ? ? ? type: String,
? ? ? ? default: ''
? ? },
? ? type: {
? ? ? ? type: String,
? ? ? ? validator: (value) => {
? ? ? ? ? ? return ['confirm', 'prompt'].includes(value)
? ? ? ? }
? ? },
? ? ok: {
? ? ? ? type: String,
? ? ? ? default: 'OK'
? ? },
? ? cancel: {
? ? ? ? type: String,
? ? ? ? default: ''
? ? },
? ? onDestroy: Function,
? ? onOK: Function,
? ? onCancel: Function
})
const promptContent = ref('')
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
? ? ? ? ? ? })
? ? }
}
const visiable = ref(false);
const setVisiable = (vis) => {
? ? visiable.value = vis;
}
const okBtnClicked = () => {
? ? setVisiable(false);
? ? onOK(promptContent.value)
}
const cancelBtnClicked = () => {
? ? setVisiable(false)
? ? onCancel()
}
onMounted(() => {
? ? setVisiable(true);
})
</script>
<style scoped>
.btn {
? ? @apply outline-gray-100 border-none p-1 rounded bg-warm-gray-200
}
.btn-primary {
? ? @apply bg-sky-300
}
.messagebox-input {
? ? @apply border rounded border-light-900 outline-none w-full py-1 px-2 text-lg?
}
.messagebox-fade-enter-from,
.messagebox-fade-leave-to {
? ? @apply opacity-0
}
.messagebox-fade-enter-active,
.messagebox-fade-leave-active {
? ? @apply transition-opacity
}
</style>

函數(shù)式組件

// 第一個參數(shù)是 props,第二個參數(shù)是 context,類似 setup 的參數(shù)
// 返回值為 VNode
// 可以導出或者直接在組件內(nèi)部使用
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 顯示函數(shù)

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 傳入回調(diào),實現(xiàn)按鈕點擊事件的傳遞、MessageBox 關(guān)閉時取消掛載的操作。

另外可以通過 MessageBox.prompt 等靜態(tài)方法直接調(diào)用對應(yīng) type 的 MessageBox,實現(xiàn)方式是在 MessageBox 上掛上對應(yīng)的靜態(tài)方法,并且覆蓋 options 的 type 選項。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • Vue?Hook?封裝通用型表格的詳細過程

    Vue?Hook?封裝通用型表格的詳細過程

    這篇文章主要介紹了Vue?Hook?封裝通用型表格,設(shè)計通用型表格組件首先,需要設(shè)計一個基礎(chǔ)的表格組件,它接受列配置、數(shù)據(jù)和分頁信息等參數(shù),本文給大家介紹的非常詳細,需要的朋友可以參考下
    2024-08-08
  • vue導出excel多層表頭的實現(xiàn)方案詳解

    vue導出excel多層表頭的實現(xiàn)方案詳解

    這篇文章主要為大家詳細介紹了vue導出excel多層表頭的實現(xiàn)方案,文中的示例代碼簡潔易懂,具有一定的借鑒價值,有需要的小伙伴可以跟隨小編一起學習一下
    2025-04-04
  • Vue Computed中g(shù)et和set的用法及Computed與watch的區(qū)別

    Vue Computed中g(shù)et和set的用法及Computed與watch的區(qū)別

    這篇文章主要介紹了Vue Computed中g(shù)et和set的用法及Computed與watch的區(qū)別,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Vue項目線上更新無需強制刷新的幾種實現(xiàn)方案(無感更新)

    Vue項目線上更新無需強制刷新的幾種實現(xiàn)方案(無感更新)

    在 Vue 項目中,當發(fā)布新版本后,用戶可能因為瀏覽器緩存而繼續(xù)使用舊版本,所以本文給大家介紹了Vue 項目線上更新無需強制刷新的幾種實現(xiàn)方案,并通過代碼示例講解的非常詳細,需要的朋友可以參考下
    2025-03-03
  • vue2.x中$attrs的使用方法教程

    vue2.x中$attrs的使用方法教程

    正常情況下Vue推薦用props向子組件參數(shù),但是在特定場景下,使用$attrs會更方便,下面這篇文章主要給大家介紹了關(guān)于vue2.x中$attrs使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • Vue?mergeProps用法詳細講解

    Vue?mergeProps用法詳細講解

    這篇文章主要介紹了Vue?mergeProps用法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-10-10
  • Vue實現(xiàn)鼠標懸浮隱藏與顯示圖片效果@mouseenter和@mouseleave事件詳解

    Vue實現(xiàn)鼠標懸浮隱藏與顯示圖片效果@mouseenter和@mouseleave事件詳解

    在所做的Vue項目中,有時候需要在鼠標移動文字框的時候顯示一些詳細信息,下面這篇文章主要給大家介紹了關(guān)于Vue實現(xiàn)鼠標懸浮隱藏與顯示圖片效果@mouseenter和@mouseleave事件的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • vue+express+jwt持久化登錄的方法

    vue+express+jwt持久化登錄的方法

    這篇文章主要介紹了vue+express+jwt持久化登錄的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • vuex實現(xiàn)歷史記錄的示例代碼

    vuex實現(xiàn)歷史記錄的示例代碼

    這篇文章主要介紹了vuex實現(xiàn)歷史記錄的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • vue3網(wǎng)絡(luò)請求添加loading過程

    vue3網(wǎng)絡(luò)請求添加loading過程

    這篇文章主要介紹了vue3網(wǎng)絡(luò)請求添加loading過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08

最新評論

开远市| 壤塘县| 湄潭县| 陆良县| 瓮安县| 沅陵县| 灵宝市| 大宁县| 安宁市| 海门市| 黑龙江省| 资兴市| 郧西县| 尤溪县| 张家港市| 江川县| 滦南县| 隆子县| 德格县| 黄浦区| 嘉荫县| 田林县| 乌兰浩特市| 塘沽区| 南康市| 曲靖市| 定陶县| 乳源| 同江市| 天气| 宣恩县| 双柏县| 常州市| 芦溪县| 衢州市| 柯坪县| 永宁县| 康乐县| 贵阳市| 蕲春县| 江山市|