搜索
您的当前位置:首页正文

vue组件挂载到全局方法的示例代码

2020-11-27 来源:抵帆知识网

在最近的项目中,使用了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;
 width: 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
Top