| 
                        副标题[/!--empirenews.page--]
                        
                          
短视频,自媒体,达人种草一站服务
 
这篇文章主要介绍了仿照Element-ui实现一个简易的$message方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 
前言 
在需要对用户进行提示时,有时会遇到这种场景:使用模态框提示太过硬核,使用toast提示又太轻了,这时候可以选择使用页面顶部滑下的消息提示。本文仿照element-ui的实现一个类似$message的方法。 
思路梳理 
首先我们来看下element-ui中消息提示的效果是怎么样的,找些思路。 
从图中我们可以看消息提示是可以同时显示多条的,并且定位看起来都是fixed,居中展示,我们自然可以想到使用数组来存储这些消息的信息,并且根据每一条提示消息的显示隐藏更改每一项的top值,然后就是加一些动画(使用transition)以及细节处理了。 
组件编写 
新建两个组件MsgBox.vue和Msg.vue,前者负责收集和处理传入的消息数据(如:{type: 'success', message: '提示消息'}),对数组进行一定处理后,再将每一项传给Msg.vue展示。 
MsgBox组件 
ts部分 
我们首先在MsgBox.vue中编写方法处理数组的方法addMsg、resetTop和clear,其中addMsg负责收集消息数据,给每一个msg添加一个负责控制该条消息显示隐藏的属性show;resetTop负责控制消息距顶距离的属性top及各条消息的显示隐藏;clear负责当数组中所有消息都处于隐藏状态时将消息数组清空: 
private addMsg(msg: Msg) {  this.msgs.push({...msg, show: true})  this.resetTop() } 
private resetTop(ind1 = -1) {  this.clear()  let ind = 0  const msgs = this.msgs.map((msg: MsgInfo, i: number) => {   if (i === ind1) {    msg.show = false   }   if (msg.show) {    msg.top = 20 + ind * 72    ind++   }   return msg  })  this.msgs = [...msgs] } 
private clear() {  clearTimeout(this.timer)  this.timer = setTimeout(() => {   const allFalse = this.msgs.some((t) => t.show)   if (!allFalse) {    this.msgs = []   }  }, 1000) } 
每次有新消息加入,或者原有消息隐藏时都会触发resetTop方法,用来重新计算各条消息的位置。 
template部分 
html部分就比较简单了,只是遍历msgs数组,将每一项传给子组件Msg。 
<template> <div>   <msg-box v-for="(msg,i) of msgs" :msg="msg" :key="i" :ind="i" @resetTop="resetTop" :msgs="msgs"></msg-box> </div> </template> 
这里传入数组msgs的原因是在每次调用resetTop更改数组时,子组件监听不到msg发生的变化,只好将msgs传入,直接从msgs中取相关数据,如果哪位大佬看出问题了希望可以指点下。 
Msg组件 
ts部分 
子组件中逻辑较少,主要是在组件挂载时启动一个定时器,在一定时间后通过emit触发父组件中的resetTop方法将组件关闭。 另外还有一些根据参数获取当前消息信息的computed方法。 
private get info() {  const msgs = this.msgs as MsgInfo[]  return msgs[this.ind] } 
private get boxClass() {  const type = this.msg.type  return type ? `box-item-${type}` : '' } 
@Emit('resetTop') private close() {   return this.ind } 
private mounted() {  if (this.msg.delay !== 0) {  const delay = parseInt(this.msg.delay) || 3000  setTimeout(() => {   this.close()  }, delay)  } } 
template部分 
视图部分也比较简单,主要是使用了vue自带的transition组件实现的动画效果,注意要加上appear属性才有入场动画效果。 
<template>  <transition appear>   <div :class="['box-item', boxClass]" v-if="info.show" :style="{top: info.top + 'px'}">    <div>    <i :class="['iconfont', iconClass]"></i>     {{ info.msg }}    </div>    <span @click="close">     <i></i>    </span>   </div>  </transition> </template> 
css部分 
样式部分主要是借鉴了element-ui的样式,以及使用了animation做了简单的动画效果 
.box-item {  height: 16px;  position: fixed;  min-width: 380px;  // element-ui抄来的样式  border-width: 1px;  border-style: solid;  border-color: #EBEEF5;  position: fixed;  left: 50%;  transform: translateX(-50%);  background-color: #edf2fc;  transition: opacity .3s,transform .4s,top .4s;  padding: 15px 15px 15px 20px;  display: flex;  align-items: center;  justify-content: space-between;  &-success{   background-color: #f0f9eb;   border-color: #e1f3d8;  }  &-warning {   background-color: #fdf6ec;   border-color: #faecd8;  }  &-error {   background-color: #fef0f0;   border-color: #fde2e2;  } } 
.msg-container {   display: flex;   align-items: center;   .iconfont {    margin-right: 5px;   } } 
.msg-enter-active {  animation: anim 0.5s; } 
.msg-leave-active {  animation: anim 0.5s reverse; } 
@keyframes anim {  0% {   opacity: 0;   transform: translate(-50%, -200%);  } 
100% {   opacity: 1;   transform: translate(-50%, 0);  } } 
到此为止,除css代码外不到150行实现了消息提示组件。 
将组件中方法放到Vue原型链上 
                        
                                                (编辑:泰州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |