一、前言
当Vue项目中ElementUI
的confirm
提示不满足我们的样式需求时,一般我们会修改全局样式,或者封装一个dialog
弹窗组件用于消息的提示和操作。
如果封装一个dialog作为组件引入,必然需要一个visible
变量来控制显隐,是否显示确认、取消按钮的变量及它们的回调函数,如果一个页面需要二次提示的地方太多,那就会显得模版臃肿、需要维护的变量变多,不优雅,使用成本变高。
xml
<!-- 是否取消订单 -->
<tips-dialog :visible.sync="dialogVisible.cancelTips" title="确认取消该订单吗?" :on-submit-c-b="cancelOrder" />
<!-- 是否删除订单 -->
<tips-dialog :visible.sync="dialogVisible.removeTips" title="确认删除该订单吗?" :message="删除后将无法恢复。" :on-submit-c-b="deleteOrder" />
···
···
现在想让使用成本变低,可以考虑使用命令式组件
的方式
二、命令式组件
命令式组件是通过编程的方式动态创建、挂载、销毁的
命令式组件的优点:
1、动态控制:可以根据用户行为或程序逻辑动态的创建和销毁组件。
2、灵活性:可以在代码任何部分创建组件爱你,并且可以动态传递参数或数据
3、代码隔离:有助于逻辑的封装和隔离
三、代码实践
弹窗vue模板
xml
<template>
<div class="confirm-wrap">
<div class="main">
<div class="title">{{ title }}</div>
<p class="message">{{ message }}</p>
<div class="btn-grounp">
<button v-if="showCancelButton" class="cancel-btn" @click="$emit('cancel')">{{ cancelButtonText }}</button>
<button v-if="showConfirmButton" class="confirm-btn" @click="$emit('confirm')">{{ confirmButtonText }}</button>
</div>
</div>
</div>
</template>
<style scoped lang="less">
.confirm-wrap {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.3);
.main {
width: 30%;
padding: 24px;
background: #fff;
border-radius: 3px;
.title {
color: #202d40;
font-size: 16px;
}
.message {
margin-top: 10px;
color: #899099;
font-size: 14px;
}
.btn-grounp {
display: flex;
justify-content: flex-end;
margin-top: 24px;
}
button {
box-sizing: border-box;
margin-left: 12px;
padding: 0px 22px;
font-size: 14px;
line-height: 32px;
cursor: pointer;
}
.confirm-btn {
color: #fff;
background: #006aff;
}
.cancel-btn {
color: #899099;
background: #fff;
border: 1px solid #edeef2;
}
}
}
</style>
js部分,以$ygConfirm挂载到Vue的原型上
javascript
import Vue from 'vue'
import MessageBox from './index.vue'
const MessageBoxConstructor = Vue.extend(MessageBox)
const defualtOptions = {
confirmButtonText: '确定',
cancelButtonText: '取消',
showConfirmButton: true,
showCancelButton: true
}
// 模拟elementUI的用法
const confirm = function (message, title, options = {}) {
if (typeof title === Object && title!==null) {
options = title
title = ''
}
options = { ...defualtOptions, message, title , ...options)
const instance = new MessageBoxConstructor({
data: options
})
// 挂载到body上
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
// 销毁实例
const removeVM = () => {
instance.vm.$destroy()
document.body.removeChild(instance.vm.$el)
}
// 监听确认和取消事件,由$emit触发
return new Promise((resolve, reject) => {
instance.vm.$on('confirm', () => {
resolve()
removeVM()
})
instance.vm.$on('cancel', () => {
reject()
removeVM()
})
})
}
export default confirm
使用
javascript
this.$ygConfirm('你好啊啊啊啊啊','test').then(()=>{
console.log('点击了确认~')
}).catch(()=>{
console.log('点击了取消~')
})
效果图