详解Vue全局组件的挂载之实现弹窗组件
w的小wife 人气:0vue组件挂载类型
vue中组件的挂载分为两种类型:
vue.extend()
render函数
组件挂载代码示例
1.vue.extend()方法
此处实现一个弹窗组件,包含确定取消按钮
msgBox.vue文件:(此处样式可自行修改)
<template> <div v-if="showMsgBox" class="mag-box"> <transition enter-active-class="animated bounceInDown" leave-active-class="animated bounceOutUp"> <div class="mask-div"> <div class="msg-tip"> <div class="msg-title"> <p>提示</p> </div> <div class="msg-content"> {{ msgTip }} </div> <div class="msg-btn-group flex-end"> <div v-show="msgType === 1" class="msg-btn cancle-btn" @click="cancleMsg"> <p>取消</p> </div> <div v-show="msgType < 2" class="msg-btn confirm-btn" @click="confirmMsg"> <p>确定</p> </div> </div> </div> </div> </transition> </div> </template> <script> export default { name: 'MsgBox', data() { return { msgTip: '', showMsgBox: false, msgType: '', // 0 只显示确定 1 确定 取消 2 都不显示 3整个组件不显示 success: '', cancle: '' } }, methods: { open({ msgTip, msgType = 1, success, cancle }) { this.showMsgBox = true this.msgType = msgType this.msgTip = msgTip this.success = success this.cancle = cancle }, confirmMsg() { this.showMsgBox = false this.success() // 组件关闭后销毁该组件 this.remove() }, cancleMsg() { this.showMsgBox = false this.cancle() this.remove() } } } </script> <style scoped lang="less"> .mask-div { position: fixed; width: 100%; height: 100%; z-index: 5000; left: 0; right: 0; top: 0; bottom: 0; background: rgba(32,42,59,0.5); } .msg-tip { width:378px; height:145px; box-shadow:0 3px 6px rgba(0,0,0,0.16); background: #ffffff; border-radius:4px; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; z-index: 9999; } .msg-title { width: 100%; height:36px; background-color:#1f95ee; border-radius:4px 4px 0 0; p { color: #ffffff; font-size: 16px; line-height: 36px; text-align: center; } } .msg-content { padding: 20px; width: 100%; box-sizing: border-box; font-size: 14px; } .msg-btn-group { position: absolute; bottom: 20px; right: 20px; .msg-btn { padding: 6px 10px; cursor: pointer; border-radius: 4px; p { font-size: 12px; border-radius: 4px; } } .cancle-btn { background: #fff; border: 1px solid #dcdfe6; color: #606266; } .confirm-btn { color: #fff; background-color: #409eff; border-color: #409eff; margin-left: 10px; } } </style>
msgBox.js文件:
// 导入msgBox的vue文件 import msgBox from './msgBox' const msgBox = { install: function(Vue) { // 组件注册 const Msg = Vue.extend(msgBox) const msg = new Msg() // 挂载 // 此处展示了两个盒子,是因为vue.extend方法挂载会覆盖原有的dom元素,销毁后便无法再次挂载 document.body.innerHTML += '<div id="msg"><div id="msg"></div></div>' msg.$mount('#msg') // 全局注册 Vue.prototype.$msgBoxInfo = function(options) { // 打开弹窗触发的方法 msg.open(options) // 弹窗关闭后销毁组件 msg.remove = function() { const msgDom = document.getElementById('msg') document.body.removeChild(msgDom) msg.$destroy() } return msg } } } export default msgBox
main.js文件内引入使用:
// 此处根据实际路径引入 import msgBoxfrom './msgBox' Vue.use(msgBox)
调用方式:
this.$msgBoxInfo({ msgTip: '这是新的msgbox', success: () => { alert('成功状态的msgbox') }, cancle:() => { alert('取消状态的msgbox') } })
vue.extend()中的data是一个函数并且返回一个对象;且会覆盖被挂载的dom元素;
同时也需要注意install方法能够开发新的插件并且注册全局组件。并且用install注册的组件,在main.js文件内引用的时候,需要使用Vue.use()进行全局声明。
2.render函数挂载
notice.vue文件(此处弹窗比较粗糙,样式自行修改)
<template> <div class="box"> <h3>{{ title }}</h3> <div class="box-content">{{ message }}</div> </div> </template> <script> export default { name: 'Notice', props: { title: { type: String, default: '' }, message: { type: String, default: '' }, duration: { type: Number, default: 1000 } }, data() { return { iShow: false } }, methods: { show() { this.iShow = true setTimeout(this.hide, this.duration) }, hide() { this.iShow = false this.remove() } } } </script> <style scoped> .box { position: fixed; width: 300px; top: 100px; right: 0; text-align: center; pointer-events: none; background-color: #fff; border: grey 3px solid; box-sizing: border-box; } .box-content { width: 200px; margin: 10px auto; font-size: 14px; padding: 8px 16px; background: #fff; border-radius: 3px; margin-bottom: 8px; } </style>
notice.js文件
import Vue from 'vue' function notice(Component, props) { const vm = new Vue({ render: h => h(Component, { props }) }).$mount() document.body.appendChild(vm.$el) const comp = vm.$children[0] // 需要对挂载的组件进行删除 comp.remove = function() { document.body.removeChild(vm.$el) vm.$destroy() } return comp } export default notice
main.js文件引入:
import create from './notice' Vue.prototype.$create = create
方法调用:
import Notice from '../Notice' // 此处的notice组件需要引入 this.$create(Notice, { title: '自己封装弹窗', message: '你好,这是自己写的弹窗', duration: 1000 }).show()
render函数作用:是vue通过js渲染dom结构的函数createElement,可以简写为h;这个函数会生成一个虚拟dom节点,render函数得到这个dom节点函数之后,返回给mount函数,渲染为真实的dom节点,并挂载到根节点上。
加载全部内容