zoukankan      html  css  js  c++  java
  • vue组件挂载到全局方法

    在最近的项目中,使用了bootstrap-vue来开发,然而在实际的开发过程中却发现这个UI提供的组件并不能打到我们预期的效果,像alert、modal等组件每个页面引入就得重复引入,并不像element那样可以通过this.$xxx来调用,那么问题来了,如何通过this.$xxx来调用起我们定义的组件或对我们所使用的UI框架的组件呢。
    bootstrap-vue中的Alert组件为例,分一下几步进行:

    1、定义一个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;
       600px;
      top: 80px;
      left: 50%;
      margin-left: -200px;
      z-index: 2000;
      font-size: 1.5rem;
    }
    </style>
    

    这里主要就是对组件参数、回调事件的一些处理,与其他处理组件的情况没有什么区别

    2、定义一个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下

    3、最后需要在main.js中use一下

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

    4、使用

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

    5、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一起讨论学习。

    来源:https://segmentfault.com/a/1190000015843132

  • 相关阅读:
    [2020.12.5周六]Boruvka
    [2020.12.4周五] 圆上对称博弈
    [2020.12.3周四]最长上升子序列
    置顶~ 未来半年内训练计划
    cf1473d
    cf1474D
    寒假复健第一天 cf1475D
    来啦来啦,寒假复健第一题cf1475g
    12.1加训总结 2019南京
    12.7-12.13训练计划
  • 原文地址:https://www.cnblogs.com/qixidi/p/10149763.html
Copyright © 2011-2022 走看看