乱码乱a∨中文字幕,在线免费激情视频,亚洲欧美久久夜夜潮,国产在线网址

  1. <sub id="hjl7n"></sub>

    1. <sub id="hjl7n"></sub>

      <legend id="hjl7n"></legend>

      當(dāng)前位置:首頁 >  站長 >  編程技術(shù) >  正文

      仿照Element-ui實現(xiàn)一個簡易的$message方法

       2020-10-28 13:57  來源: 腳本之家   我來投稿 撤稿糾錯

        阿里云優(yōu)惠券 先領(lǐng)券再下單

      這篇文章主要介紹了仿照Element-ui實現(xiàn)一個簡易的$message方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

      前言

      在需要對用戶進(jìn)行提示時,有時會遇到這種場景:使用模態(tài)框提示太過硬核,使用toast提示又太輕了,這時候可以選擇使用頁面頂部滑下的消息提示。本文仿照element-ui的實現(xiàn)一個類似$message的方法。

      思路梳理

      首先我們來看下element-ui中消息提示的效果是怎么樣的,找些思路。

      從圖中我們可以看消息提示是可以同時顯示多條的,并且定位看起來都是fixed,居中展示,我們自然可以想到使用數(shù)組來存儲這些消息的信息,并且根據(jù)每一條提示消息的顯示隱藏更改每一項的top值,然后就是加一些動畫(使用transition)以及細(xì)節(jié)處理了。

      組件編寫

      新建兩個組件MsgBox.vue和Msg.vue,前者負(fù)責(zé)收集和處理傳入的消息數(shù)據(jù)(如:{type: 'success', message: '提示消息'}),對數(shù)組進(jìn)行一定處理后,再將每一項傳給Msg.vue展示。

      MsgBox組件

      ts部分

      我們首先在MsgBox.vue中編寫方法處理數(shù)組的方法addMsg、resetTop和clear,其中addMsg負(fù)責(zé)收集消息數(shù)據(jù),給每一個msg添加一個負(fù)責(zé)控制該條消息顯示隱藏的屬性show;resetTop負(fù)責(zé)控制消息距頂距離的屬性top及各條消息的顯示隱藏;clear負(fù)責(zé)當(dāng)數(shù)組中所有消息都處于隱藏狀態(tài)時將消息數(shù)組清空:

      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)
      }

      每次有新消息加入,或者原有消息隱藏時都會觸發(fā)resetTop方法,用來重新計算各條消息的位置。

      template部分

      html部分就比較簡單了,只是遍歷msgs數(shù)組,將每一項傳給子組件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>

      這里傳入數(shù)組msgs的原因是在每次調(diào)用resetTop更改數(shù)組時,子組件監(jiān)聽不到msg發(fā)生的變化,只好將msgs傳入,直接從msgs中取相關(guān)數(shù)據(jù),如果哪位大佬看出問題了希望可以指點下。

      Msg組件

      ts部分

      子組件中邏輯較少,主要是在組件掛載時啟動一個定時器,在一定時間后通過emit觸發(fā)父組件中的resetTop方法將組件關(guān)閉。 另外還有一些根據(jù)參數(shù)獲取當(dāng)前消息信息的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組件實現(xiàn)的動畫效果,注意要加上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行實現(xiàn)了消息提示組件。

      將組件中方法放到Vue原型鏈上

      但是我們該怎么調(diào)用呢,參考element-ui中的使用方式this.$message,是把組件的入口方法掛載到Vue的原型鏈上,并且在此之前應(yīng)該實例化了該組件,接下來我們就要實例化組件,然后將組件實例掛載到body上,并且將實例上的入口方法加在Vue原型鏈上。

      這里使用到了我們公司一位大佬參考react寫的vue中的傳送門方法portal,主要思路是將組件掛載新的Vue上,并實例化,然后再將新實例掛載到body下面(這樣也防止DOM層級嵌套產(chǎn)生的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組件掛載上去就可以在組件中使用了。

      到此這篇關(guān)于仿照Element-ui實現(xiàn)一個簡易的$message方法的文章就介紹到這了,更多相關(guān)Element-ui $message內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

      來源:腳本之家

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

      申請創(chuàng)業(yè)報道,分享創(chuàng)業(yè)好點子。點擊此處,共同探討創(chuàng)業(yè)新機遇!

      相關(guān)文章

      熱門排行

      信息推薦