仿ElMessage,自行封装一个全局message消息提醒
仿照element-plus的message消息提醒,自行封装一个简化版的全局message消息提醒
实现功能:
- 可以选择类型,如success、warning、error
 
- 通过vue插件或函数使用
 
但多次触发消息提示,只有一个消息提示框,目前还没实现多次触发弹出多个提示框
实现代码如下:
src/components/Message/index.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
   | <template>      <div     v-if="showMessage"     :class="[       'message-box',       activeClass,       showMessage ? 'message-box-active' : '',     ]"   >     <div class="message-body">       <span class="icon">{{ icon }}</span>       <span class="text">{{ messageText }}</span>     </div>   </div> </template>
  <script setup> import { ref } from "vue"; const showMessage = ref(false); const activeClass = ref(""); const time = ref(0); const messageText = ref(""); const icon = ref(""); const iconType = {   success: "√",   warning: "!",   error: "×", };
  const handlerShow = ({   type = "success",   duration = 3000,   text = "消息提示", }) => {      showMessage.value = true;      activeClass.value = type;        icon.value = iconType[type]      messageText.value = text;      time.value = duration;      setTimeout(() => {     showMessage.value = false;   }, time.value); };
 
  defineExpose({   handlerShow, }); </script>
  <style lang="scss"> .message-box {   position: fixed;   top: 0;   z-index: 9;   min-width: 300px;   border-radius: 4px;   border: 1px solid #ebeef5;   left: 50%;   transform: translateX(-50%);   overflow: hidden;   padding: 15px 15px 15px 20px;   opacity: 0;   transition: opacity 0.3s, transform 0.4s, top 0.4s;   .message-body {     display: flex;     align-items: center;   }   .text {     font-size: 14px;   }   .icon {     display: inline-block;     text-align: center;     width: 20px;     height: 20px;     text-align: center;     //   padding: 5px;     line-height: 20px;     color: white;     border-radius: 50%;     font-size: 12px;     margin-right: 10px;   } } .message-box-active {   opacity: 1;   top: 10vh; } .success {   background: #f0f9eb;   border-color: #e1f3d8;   .text {     color: #52ac25;   }   .icon {     background: #52ac25;   } } .warning {   background: #fdf6ec;   border-color: #faecd8;   .text {     color: #e6a23c;   }   .icon {     background: #e6a23c;   } } .error {   background: #fef0f0;   border-color: #fde2e2;   .text {     color: #f56c6c;   }   .icon {     background: #f56c6c;   } } </style>
   | 
 
src/components/Message/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
   | import Message from './index.vue' import { createVNode, render } from 'vue'
 
  export default {          install(app) {                  const Vnode = createVNode(Message);                  render(Vnode, document.body);                  app.config.globalProperties.$message = Vnode.component.exposed.handlerShow     },
           service({         type = "success",         duration = 3000,         text = "消息提示",     }) {         const vm = createVNode(Message);                  render(vm, document.body);                  vm.component.exposed.handlerShow({type,duration,text})     }
                                                                                       }
   | 
 
src/main.js(如果当作插件来使用就需要app.use(…))
1 2 3
   | import Message from './components/Message' ... app.use(Message)
   |