vue組件掛載到全局方法

在最近的項目中,使用了bootstrap-vue來開發,然而在實際的開發過程當中卻發現這個UI提供的組件並不能打到咱們預期的效果,像alert、modal等組件每一個頁面引入就得重複引入,並不像element那樣能夠經過this.$xxx來調用,那麼問題來了,如何經過this.$xxx來調用起咱們定義的組件或對咱們所使用的UI框架的組件呢。
bootstrap-vue中的Alert組件爲例,分一下幾步進行:vue

一、定義一個vue文件實現對原組件的再次封裝

main.vue
<template>
  <b-alert
    class="alert-wrap pt-4 pb-4"
    :show="isAutoClose"
    :variant="type" dismissible
    :fade="true"
    @dismiss-count-down="countDownChanged"
    @dismissed="dismiss"
    >
     {{msg}}
    </b-alert>
</template>
<script>
export default {
  /**
   * 參考: https://bootstrap-vue.js.org/docs/components/alert
   * @param {string|number} msg 彈框內容
   * @param {tstring} type 彈出框類型 對應bootstrap-vue中variant 可選值有:'primary'、'secondary'、'success'、'danger'、'warning'、'info'、'light'、'dark'默認值爲 'info'
   * @param {boolean} autoClose 是否自動關閉彈出框
   * @param {number} duration 彈出框存在時間(單位:秒)
   * @param {function} closed 彈出框關閉,手動及自動關閉都會觸發
   */
  props: {
    msg: {
      type: [String, Number],
      default: ''
    },
    type: {
      type: String,
      default: 'info'
    },
    autoClose: {
      type: Boolean,
      default: true
    },
    duration: {
      type: Number,
      default: 3
    },
    closed: {
      type: Function,
      default: null
    }
  },
  methods: {
    dismiss () {
      this.duration = 0
    },
    countDownChanged (duration) {
      this.duration = duration
    }
  },
  computed: {
    isAutoClose () {
      if (this.autoClose) {
        return this.duration
      } else {
        return true
      }
    }
  },
  watch: {
    duration () {
      if (this.duration === 0) {
        if (this.closed) this.closed()
      }
    }
  }
}
</script>
<style scoped>
.alert-wrap {
  position: fixed;
  width: 600px;
  top: 80px;
  left: 50%;
  margin-left: -200px;
  z-index: 2000;
  font-size: 1.5rem;
}
</style>

這裏主要就是對組件參數、回調事件的一些處理,與其餘處理組件的狀況沒有什麼區別bootstrap

二、定義一個js文件掛載到Vue上,並和咱們定義的組件進行交互

index.js
import Alert from './main.vue'
import Vue from 'vue'
let AlertConstructor = Vue.extend(Alert)
let instance
let seed = 1
let index = 2000
const install = () => {
  Object.defineProperty(Vue.prototype, '$alert', {
    get () {
      let id = 'message_' + seed++
      const alertMsg = options => {
        instance = new AlertConstructor({
          propsData: options
        })
        index++
        instance.id = id
        instance.vm = instance.$mount()
        document.body.appendChild(instance.vm.$el)
        instance.vm.$el.style.zIndex = index
        return instance.vm
      }
      return alertMsg
    }
  })
}
export default install

其主要思想是經過調用這個方法給組件傳值,而後append到body下app

三、最後須要在main.js中use一下

import Alert from '@/components/alert/index'
Vue.use(Alert)

四、使用

this.$alert({msg: '歡迎━(*`∀´*)ノ亻!'})

五、confrim的封裝也是同樣的

main.vue
<template>
  <b-modal
    v-if="!destroy"
    v-model="isShow"
    title="舒適提示"
    @change="modalChange"
    @show="modalShow"
    @shown="modalShown"
    @hide="modalHide"
    @hidden="modalHidden"
    @ok="modalOk"
    @cancel="modalCancel"
    :centered="true"
    :hide-header-close="hideHeaderClose"
    :no-close-on-backdrop="noCloseOnBackdrop"
    :no-close-on-esc="noCloseOnEsc"
    :cancel-title="cancelTitle"
    :ok-title="okTitle">
      <p class="my-4">{{msg}}</p>
  </b-modal>
</template>
<script>
export default {
  /**
   * 參考: https://bootstrap-vue.js.org/docs/components/modal
   * @param {boolean} isShow 是否顯示modal框
   * @param {string|number} msg 展現內容
   * @param {boolean} hideHeaderClose 是否展現右上角關閉按鈕 默認展現
   * @param {string} cancelTitle 取消按鈕文字
   * @param {string} okTitle 肯定按鈕文字
   * @param {boolean} noCloseOnBackdrop 可否經過點擊外部區域關閉彈框
   * @param {boolean} noCloseOnEsc 可否經過鍵盤Esc按鍵關閉彈框
   * @param {function} change 事件觸發順序: show -> change -> shown -> cancel | ok -> hide -> change -> hidden
   * @param {function} show before modal is shown
   * @param {function} shown modal is shown
   * @param {function} hide before modal has hidden
   * @param {function} hidden after modal is hidden
   * @param {function} ok 點擊'肯定'按鈕
   * @param {function} cancel 點擊'取消'按鈕
   * @param {Boolean} destroy 組件是否銷燬 在官方並無找到手動銷燬組件的方法,只能經過v-if來實現
   */
  props: {
    isShow: {
      type: Boolean,
      default: true
    },
    msg: {
      type: [String, Number],
      default: ''
    },
    hideHeaderClose: {
      type: Boolean,
      default: false
    },
    cancelTitle: {
      type: String,
      default: '取消'
    },
    okTitle: {
      type: String,
      default: '肯定'
    },
    noCloseOnBackdrop: {
      type: Boolean,
      default: true
    },
    noCloseOnEsc: {
      type: Boolean,
      default: true
    },
    change: {
      type: Function,
      default: null
    },
    show: {
      type: Function,
      default: null
    },
    shown: {
      type: Function,
      default: null
    },
    hide: {
      type: Function,
      default: null
    },
    hidden: {
      type: Function,
      default: null
    },
    ok: {
      type: Function,
      default: null
    },
    cancel: {
      type: Function,
      default: null
    },
    destroy: {
      type: Boolean,
      default: false
    }
  },
  methods: {
    modalChange () {
      if (this.change) this.change()
    },
    modalShow () {
      if (this.show) this.show()
    },
    modalShown () {
      if (this.shown) this.shown()
    },
    modalHide () {
      if (this.hide) this.hide()
    },
    modalHidden () {
      if (this.hidden) this.hidden()
      this.destroy = true
    },
    modalOk () {
      if (this.ok) this.ok()
    },
    modalCancel () {
      if (this.cancel) this.cancel()
    }
  }
}
</script>
index.js
import Confirm from './main.vue'
import Vue from 'vue'
let ConfirmConstructor = Vue.extend(Confirm)
let instance
let seed = 1
let index = 1000
const install = () => {
  Object.defineProperty(Vue.prototype, '$confirm', {
    get () {
      let id = 'message_' + seed++
      const confirmMsg = options => {
        instance = new ConfirmConstructor({
          propsData: options
        })
        index++
        instance.id = id
        instance.vm = instance.$mount()
        document.body.appendChild(instance.vm.$el)
        instance.vm.$el.style.zIndex = index
        return instance.vm
      }
      return confirmMsg
    }
  })
}
export default install

求知的慾望,是不斷學習的動力。路漫漫其修遠兮,吾將上下而求索。歡迎加我QQ:2360263057一塊兒討論學習。框架

相關文章
相關標籤/搜索