用Vue.extend()來做一個(gè)全局提示組件

相信很多人用vuejs構(gòu)建單頁應(yīng)用時(shí)都會(huì)用到一些全局方法,比如發(fā)ajax請(qǐng)求時(shí)喜歡用axios掛載到vue原型上鸟召,如下:

// 1 引入vue和axios
import Vue from 'vue'
import axios from 'axios'
// 2 對(duì)axios的一些封裝
// code ...

// 3 然后掛載到原型上
Vue.prototype.$axios = axios

用的時(shí)候就直接上this.$axios

// 用axios.get()方法可以這樣用
this.$axios.get()

這樣確實(shí)方便,不用每個(gè)用到axios的組件都去引入

類似如此膜钓,當(dāng)我們要用到一些操作dom的方法時(shí)要怎么做呢桃煎,上面的例子純屬js的封裝,沒有涉及到dom笤受;下面我用一個(gè)全局提示組件為例穷缤,類似element-ui的message組件為大家演示一遍如何封裝一個(gè)包含操作dom的的全局組件的,步驟主要有3步:

1, 在componenets/Message 目錄下新建一個(gè)Message.vue組件
<template>
<transition name="fade">
    <div class="message" :class="type" v-show="show">
      <i class="icon"></i>
      <span class="text">{{text}}</span>
    </div>
</transition>
</template>

<script type="text/ecmascript-6">
  export default {
    name: 'message',
    props: {
      type: {
        type: String,
        default: 'info',
        validator: val => ['info', 'success', 'warning', 'error'].includes(val)
//['info', 'success', 'warning', 'error'] 表示type只接收這四個(gè)字符串作為參數(shù)傳入message組件
      },
      text: {
        type: String,
        default: ''
      },
      show: {
        type: Boolean,
        default: false
      }
    }
  }
</script>

<style scoped lang="stylus">
  @import "~@/common/style/global.styl"
   // fade動(dòng)畫 <transition name="fade"> </transition>
   // 下面的樣式可以自己改
  .fade-enter-active,
  .fade-leave-active 
     transition: opacity .3s
  .fade-enter,
  .fade-leave-to
     opacity: 0
  .message
    position fixed
    top 40px
    text-align center
    left 50%
    transform translateX(-50%)
    min-width 400px
    padding 10px 20px
    color $strong-text-color
    background #f5f5f5
    font-size 14px
    line-height 1.4
    border-radius 4px
    z-index 1000
    box-shadow 0 0 10px rgba(0, 0, 0, .3)
    &.info
      color $strong-text-color
    &.success
      color $success-color
    &.error
      color $danger-color
    &.warning
      color $warning-color
</style>
2, 在componenets/Message目錄準(zhǔn)備一個(gè)index.js
import Message from './Message.vue'

const MESSAGE = {
  duration: 3000, // 顯示的時(shí)間 ms
  animateTime: 300, // 動(dòng)畫時(shí)間,表示這個(gè)組件切換show的動(dòng)畫時(shí)間
  install(Vue) {
    if (typeof window !== 'undefined' && window.Vue) {
      Vue = window.Vue
    }
    Vue.component('Message', Message)

    function msg(type, text, callBack) {
      let msg
      let duration = MESSAGE.duration
      if (typeof text === 'string') {
        msg = text
      } else if (text instanceof Object) {
        msg = text.text || ''
        if (text.duration) {
          duration = text.duration
        }
      }
      let VueMessage = Vue.extend({
        render(h) {
          let props = {
            type,
            text: msg,
            show: this.show
          }
          return h('message', {props})
        },
        data() {
          return {
            show: false
          }
        }
      })
      let newMessage = new VueMessage()
      let vm = newMessage.$mount()
      let el = vm.$el
      document.body.appendChild(el) // 把生成的提示的dom插入body中
      vm.show = true
      let t1 = setTimeout(() => {
        clearTimeout(t1)
        vm.show = false  //隱藏提示組件箩兽,此時(shí)會(huì)有300ms的動(dòng)畫效果津肛,等動(dòng)畫效果過了再從body中移除dom
        let t2 = setTimeout(() => {
          clearTimeout(t2)
          document.body.removeChild(el) //從body中移除dom
          newMessage.$destroy()
          vm = null // 設(shè)置為null,好讓js垃圾回收算法回收汗贫,釋放內(nèi)存

          callBack && (typeof callBack === 'function') && callBack() 
      // 如果有回調(diào)函數(shù)就執(zhí)行身坐,沒有就不執(zhí)行,用&&操作符落包,
      // 只有&&左邊 的代碼為true才執(zhí)行&&右邊的代碼部蛇,避免用面條代碼:
      // if(true){
      //   ... 
      //   if(true){
      //   ...
      //   }
      // }
        }, MESSAGE.animateTime)
      }, duration)
    }

// 掛載到vue原型上,暴露四個(gè)方法
    Vue.prototype.$message = {
      info(text, callBack) {
        if (!text) return
        msg('info', text, callBack)
      },
      success(text, callBack) {
        if (!text) return
        msg('success', text, callBack)
      },
      error(text, callBack) {
        if (!text) return
        msg('error', text, callBack)
      },
      warning(text, callBack) {
        if (!text) return
        msg('warning', text, callBack)
      }
    }
  }
}
export default MESSAGE

上面的代碼關(guān)鍵點(diǎn)就是用Vue.extend()構(gòu)造出一個(gè)Vue子類實(shí)例咐蝇,(注意我這里模板渲染只用到render函數(shù)涯鲁,沒有用template選項(xiàng),因?yàn)閠emplate選項(xiàng) 要求裝Vue時(shí)要加入模板編譯器那塊代碼,用render函數(shù)更加簡(jiǎn)潔,只需要裝運(yùn)行時(shí)版本撮竿,Vue體積更加小)吮便;然后調(diào)用$mount()方法生成需要的dom,再拿到對(duì)應(yīng)的$el,實(shí)例內(nèi)部自己維護(hù)插入dom和移除dom的操作,對(duì)外暴露了四個(gè)方法info幢踏、success髓需、error、warning方便不同的場(chǎng)景調(diào)用房蝉;類似的組件還有confrim組件僚匆、alert組件等,大同小異搭幻。

3咧擂,在main.js中引入components/Message/index.js,以插件形式安裝
import Vue from 'vue'
import vMessage from './components/Message/index' 
Vue.use(vMessage)

最后,當(dāng)你需要用的時(shí)候就直接檀蹋,特別適合在ajax回調(diào)函數(shù)里面用來提示

this.$message.info('普通消息') 
this.$message.error('錯(cuò)誤消息') 
this.$message.warning('警告消息') 
this.$message.success('成功消息') 

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末松申,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子俯逾,更是在濱河造成了極大的恐慌贸桶,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桌肴,死亡現(xiàn)場(chǎng)離奇詭異皇筛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坠七,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門水醋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彪置,你說我怎么就攤上這事拄踪。” “怎么了悉稠?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵宫蛆,是天一觀的道長。 經(jīng)常有香客問我的猛,道長耀盗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任卦尊,我火速辦了婚禮叛拷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岂却。我一直安慰自己忿薇,他們只是感情好裙椭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著署浩,像睡著了一般揉燃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筋栋,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天炊汤,我揣著相機(jī)與錄音,去河邊找鬼弊攘。 笑死抢腐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的襟交。 我是一名探鬼主播迈倍,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捣域!你這毒婦竟也來了啼染?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤竟宋,失蹤者是張志新(化名)和其女友劉穎提完,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丘侠,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年逐样,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜗字。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡脂新,死狀恐怖挪捕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情争便,我是刑警寧澤级零,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站滞乙,受9級(jí)特大地震影響奏纪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斩启,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一序调、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兔簇,春花似錦发绢、人聲如沸硬耍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽经柴。三九已至,卻和暖如春墩朦,著一層夾襖步出監(jiān)牢的瞬間口锭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工介杆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鹃操,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓春哨,卻偏偏與公主長得像荆隘,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赴背,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • # 傳智播客vue 學(xué)習(xí)## 1. 什么是 Vue.js* Vue 開發(fā)手機(jī) APP 需要借助于 Weex* Vu...
    再見天才閱讀 3,525評(píng)論 0 6
  • 最近在逛各大網(wǎng)站椰拒,論壇,以及像SegmentFault等編程問答社區(qū)凰荚,發(fā)現(xiàn)Vue.js異橙脊郏火爆,重復(fù)性的提問和內(nèi)容...
    忘川慕白閱讀 5,912評(píng)論 7 113
  • 相關(guān)概念 混合開發(fā)和前后端分離 混合開發(fā)(服務(wù)器端渲染) 前后端分離后端提供接口便瑟,前端開發(fā)界面效果(專注于用戶的交...
    他愛在黑暗中漫游閱讀 2,765評(píng)論 4 45
  • ·哥特教堂的代表
    卯毛栗幾兒閱讀 2,648評(píng)論 1 1
  • 馬陵山缆毁,因七雄爭(zhēng)霸而聞名與世,這里有國家AAAA級(jí)地質(zhì)公園到涂,馬陵古道脊框,中華銀杏國與沂水相伴繞山右而立,這里有一處美...
    馬陵山下制陶人閱讀 266評(píng)論 0 0