需求分析
我敢说管理后台项目使用最多的组件非table,form,dialog莫属,那么问题来了,怎么封装一个全局组件呢?不必惊慌,在vue里面这些问题都不是问题。
一、全局注册组件
vue里面有个install方法给我们安装插件的,我们只需要在这个方法里面注册组件,然后在main.js里面导入,使用Vue.use挂载就行了。
1.新建components/common/index.js
import baseDialog from './components/baseDialog.vue'
// 全局注册组件
export default {
install: function (Vue) {
Vue.component('base-dialog', baseDialog)
}
}
2.main.js导入
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import component from '@/components/common'
Vue.config.productionTip = false
Vue.use(component)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
3.全局弹窗组件baseDialog.vue
<template>
<el-dialog
:title="title"
:visible.sync="model"
:width="width"
:before-close="handleClose"
:modal="modal"
:append-to-body="appendToBody"
:show-close="showClose"
:center="center"
:maxHeight="maxHeight"
:fullscreen="fullscreen"
@open="$emit('open')"
@close="$emit('close')"
>
<slot name="append"></slot>
<el-scrollbar>
<div :style="bodyStyle">
<slot name="body"></slot>
</div>
</el-scrollbar>
<span slot="footer" class="dialog-footer">
<slot name="footer"></slot>
</span>
</el-dialog>
</template>
<script>
/**
* baseDialog 全局弹窗
* @description 基于插槽的element-dialog弹窗封装
* @property {Boolean} model 是否显示 Dialog
* @property {String} title Dialog 的标题
* @property {String} width Dialog 的宽度
* @property {Boolean} appendToBody Dialog 自身是否插入至 body 元素上
* @property {Boolean} modal 是否需要遮罩层
* @property {Boolean} showClose 是否显示关闭按钮
* @property {Boolean} center 是否对头部和底部采用居中布局
* @property {String} maxHeight dialog 内容最大高度
* @property {Boolean} fullscreen 是否为全屏 Dialog
*/
export default {
props: {
model: {
type: Boolean,
default: false
},
title: {
type: String,
default: '弹窗'
},
width: {
type: String,
default: '40%'
},
maxHeight: {
type: String,
default: '50vh'
},
fullscreen: {
type: Boolean,
default: false
},
appendToBody: {
type: Boolean,
default: false
},
modal: {
type: Boolean,
default: true
},
showClose: {
type: Boolean,
default: true
},
center: {
type: Boolean,
default: false
}
},
computed: {
bodyStyle () {
return {
maxHeight: this.fullscreen ? '80vh' : this.maxHeight
}
}
},
methods: {
handleClose () {
this.$confirm('确认关闭?')
.then(() => {
this.$emit('close')
})
.catch((_) => {})
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .el-dialog {
.el-dialog__body {
overflow: auto;
min-height: 100px;
padding: 20px;
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
}
</style>
二、组件使用
<base-dialog :model="dialog.model" @close="closeDialog">
<template #body>
<h1>我是弹窗</h1>
</template>
<template #footer>
<el-button @click="dialog.model = false">取 消</el-button>
<el-button type="primary">确 定</el-button>
</template>
</base-dialog>
祝大家生活愉快!