模仿Element-ui實現一個淺易的$message方式_海南網賺

模仿Element-ui實現一個淺易的$message方式_海南網賺插图

 

這篇文章主要先容了模仿Element-ui實現一個淺易的$message方式,文中通過示例代碼先容的異常詳細,對人人的學習或者事情具有一定的參考學習價值,需要的朋友們下面隨着小編來一起學習學習吧

前言

在需要對用戶舉行提醒時,有時會遇到這種場景:使用模態框提醒太過硬核,使用toast提醒又太輕了,這時候可以選擇使用頁面頂部滑下的新聞提醒。本文模仿element-ui的實現一個類似$message的方式。

思緒梳理

首先我們來看下element-ui中新聞提醒的效果是怎麼樣的,找些思緒。

模仿Element-ui實現一個淺易的$message方式_海南網賺插图

從圖中我們可以看新聞提醒是可以同時显示多條的,而且定位看起來都是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}` : ”
}

開放式SEO指的是什麼 和封閉式SEO有什麼關係

很多時候,硬碰硬是解決不了問題的,而且這個世界上存在許多精神有問題的智障,他盜版了你的文章,他會覺得天經地義,你找他理論,反而會把你罵得狗血臨頭,你惹惱了他,他會找人攻擊你的網站,舉報你的網站,天天留言罵你,各種騷操作,讓你疲於應對。

大乐透单期筹公益金8290万 奖池滚存45.70亿-大乐透

1月20日,体彩大乐透第18009期前区开出号码10、12、28、30、34,后区开出号码03、04。本期全国共销售2.30亿元,为社会筹集公益金8290万元。 二等奖奖金高达54.23万 本期全国头奖空开。二等奖中出38注,每注奖金为33.89万元;其中8注采用追加投注,每注多得奖

@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 name=”msg” appear>
  <div :class=”[‘box-item’, boxClass]” v-if=”info.show” :style=”{top: info.top + ‘px’}”>
   <div class=”msg-container”>
   <i :class=”[‘iconfont’, iconClass]”></i>
    {{ info.msg }}
   </div>
   <span @click=”close”>
    <i class=”iconfont icon-cc-close”></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原型鏈上

然則我們該怎麼挪用呢,參考element-ui中的使用方式this.$message,是把組件的入口方式掛載到Vue的原型鏈上,而且在此之前應該實例化了該組件,接下來我們就要實例化組件,然後將組件實例掛載到body上,而且將實例上的入口方式加在Vue原型鏈上。

這裏使用到了我們公司一位大佬參考react寫的vue中的傳送門方式portal,主要思緒是將組件掛載新的Vue上,並實例化,然後再將新實例掛載到body下面(這樣也防止DOM層級嵌套發生的zIndex無法籠罩等問題),最後將指定方式添加到Vue原型鏈上。

import Vue, {VueConstructor} from “vue”;

interface Param {
 cmp: VueConstructor & {instance?: () => any};
 name: string;
 method?: string;
 target?: string | HTMLElement;
 props?: any;
}

export default function portal(param: Param){
  let {cmp, name, method, target = document.body, props = {}} = param
  if(typeof target === ‘string’) target = document.querySelector(target) as HTMLElement;
  method = method || ‘show’
  cmp.instance = ()=>{
    let instance = new Vue({
      render(h){
        return h(cmp, {props})
      }
    })

    instance.$mount();

    // 將instance.$el放到想放的位置
    (target as HTMLElement).appendChild(instance.$el);
    return instance.$children[0];
  }
  const instance = cmp.instance()
 
  Vue.prototype[`$${name}`] = instance[method];
}

接着,在Vue項目入口文件中使用傳送門方式將Msg組件掛載上去就可以在組件中使用了。

到此這篇關於模仿Element-ui實現一個淺易的$message方式的文章就先容到這了,更多相關Element-ui $message內容請搜索劇本之家以前的文章或繼續瀏覽下面的相關文章希望人人以後多多支持劇本之家!

泉源:劇本之家

鏈接:https://www.jb51.net/article/195577.htm

申請創業報道,分享創業好點子。,配合探討創業新機遇!

企業做SEO推廣的意義

你是一位企業老闆,你的名片上居然沒有印着企業網站,作為客戶,看到這樣的名片,多多少少會有一些擔心,及不信任的想法。哪怕企業網站一個流量也沒有,企業也要建立企業網站,要讓客戶知道,你有企業網站,客戶在意的只是你有沒有,而不是網站有多少人看。

Author: 狗蛋
狗蛋的个人中心,这里没有什么。