主要总结确认弹窗组件(comfirm)的封装,和插件封装的主要知识点
共同点
1.都需要要一个已经实现的comfirm.vue组件文件(以下是组件在vue2中的实现)
<template>
<div class="comfirm-box" v-show="modelShow">
<transition name="fade">
<div class="comfirm" v-if="show">
<div class="btn-close" @click="cancelEvent" v-if="showCloseBtn"></div>
<h4 class="title" v-if="!hideTitle">{{title}}</h4>
<div class="message"
:class="{'message-add' : addMessageDistance}"
v-html="content"></div>
<div class="btn-box" :class="{'btn-box-center':hideCancel}">
<!-- 取消按钮 -->
<div class="btn btn-cancel"
:style="{fontSize : (btnFontSize || '' )}"
@click="cancelEvent"
v-if="!hideCancel">
{{cancelText || '取消'}}
</div>
<!-- 确定按钮 -->
<div class="btn btn-submit"
:style="{fontSize : (btnFontSize || '' )}"
:class="{'big-btn-submit':hideCancel}"
@click="onOkEvent">
{{okText || '确定'}}
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import {debounce} from '@/utils/utils';
let that;
export default {
name: 'comfirm',
props : {
//标题
title : {
type : String
},
// 内容
content : {
type : String
},
//是否隐藏标题
hideTitle : {
type : Boolean,
default : false
},
//取消按钮文本
cancelText : {
type : String,
default : '取消'
},
//隐藏取消按钮
hideCancel : {
type : Boolean,
default : false
},
// 确定按钮文案
okText : {
type : String,
default : '确定'
},
//v-model对外开放值
value : {
type : Boolean
},
//按钮字体字号
btnFontSize : {
type : String
},
//显示关闭按钮
showCloseBtn : {
type : Boolean
}
},
data(){
that = this;
return{
//显示弹窗
modelShow : this.value,
show : false,
//判断是否是通过方法调用
isComfirm : false
}
},
mounted(){},
computed:{
//增加文本间距
addMessageDistance(){
let {showCloseBtn,hideTitle} = this;
//显示关闭按钮,并且隐藏标题,则增加段落文本距离顶部距离
return (showCloseBtn && hideTitle);
}
},
methods:{
//确认事件
onOkEvent : debounce(()=>{
let {onOk} = that;
//判断是否有确认回调,如果有的话执行
onOk && onOk();
//提交父组件确认事件
that.$emit('on-ok');
//关闭弹窗
that.close();
},false),
//取消事件
cancelEvent : debounce(()=>{
let {onCancel} = that;
//判断是否有取消回调
onCancel && onCancel();
try{
//提交父组件取消事件
that.$emit('on-cancel');
}
catch(err){
console.log(err);
}
//关闭弹窗
that.close();
},false),
// 关闭弹窗
close(){
let {isComfirm} = this;
//隐藏弹窗
this.modelShow = false;
if(isComfirm){
setTimeout(()=>{
// 彻底销毁实例
that.$destory && that.$destory();
//删除节点
if(that.$el && document.body.contains(that.$el)){
that.$el.remove()
}
},100);
}
}
},
watch : {
//监听外部值变化,赋值给模板显隐
value(modelShow){
this.modelShow= modelShow;
},
//监听显隐变化传递给外层组件
modelShow(value){
this.$nexttick(()=>{
this.show = value;
this.$emit('input',value);
})
}
}
}
</script>
<style lang="scss" scoped>
.comfirm-box{
width: 100%;
height: 100vh;
overflow: hidden;
background-color: rgba(0,0,0,0.3);
position: fixed;
left: 0;
top: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 11;
}
.comfirm{
padding: 40px;
border-radius: 32px;
background-color: #fff;
width: 600px;
max-height: 70vh;
box-sizing: border-box;
text-align: center;
overflow-y: auto;
position: relative;
}
.btn-close{
width: 85px;
height: 85px;
background: url(../../assets/components/comfirm/close.png) no-repeat;
background-position: center center;
position: absolute;
right: 0;
top: 0;
}
.title{
font-size: 38px;
color: #353535;
line-height: 50px;
}
.message{
font-size: 28px;
color: #353535;
line-height: 36px;
}
.message-add{
margin-top: 30px;
}
.btn-box{
display: flex;
justify-content: space-around;
margin-top: 36px;
}
.btn-box-center{
justify-content: center;
}
.btn{
min-width: 240px;
max-width: 250px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 22px;
height: 92px;
line-height: 44px;
font-size: 34px;
border: 2px solid transparent;
border-radius: 44px;
box-sizing: border-box;
}
.btn-cancel{
border-color: #EAEAEA;
color: #737373;
background-color: #FFFFFF;
}
.btn-submit{
background: #FFD321;
border-color: #FFD321;
color: #282121;
}
.big-btn-submit{
width: 320px;
max-width: 320px;
}
.fade-enter-active, .fade-leave-active {
transition: all .3s;
}
.fade-enter /* .fade-leave-active below version 2.1.8 */ {
transform: scale(0.3);
opacity: .8;
}
.fade-leave-to{
transform: scale(0.8);
opacity: .8;
}
</style>
不同点
1. vue3中使用comfirm.vue文件(功能不变的情况),有几个地方是需要改动的
//props中要增加onCancel、onOk方法的定义
//把data中的isComfirm参数移到 props中
props : {
//取消事件
onCancel : {
type : Function
},
//确认事件
onOk : {
type : Function
},
//是否为插件调用
isComfirm : {
type : Boolean
}
}
//动画样式改动
//vue3取消了 .fade-enter和.fade-leave-to
//.fade-enter-active, .fade-leave-active 样式重新调整如下
.fade-enter-active{
animation: moveIn .3s;
}
.fade-leave-active {
animation: moveOut .3s;
}
@keyframes moveIn{
from{
transform: scale(0.3);
opacity: .8;
}
to{
transform: scale(1);
opacity: 1;
}
}
@keyframes moveOut{
from{
transform: translateY(0);
opacity: 1;
}
to{
transform: translateY(100%);
opacity: 0;
}
}
2.入口文件不同
以下是vue2的入口文件
import Vue from 'vue';
//引入确认弹窗组件
import comfirm from './comfirm.vue';
// 创建一个vue子类
const ComfirmConstructor = Vue.extend(comfirm);
const Comfirm = ({
title='',
content='',
hideTitle,
hideCancel,
cancelText,
okText,
onOk,
btnFontSize,
onCancel,
showCloseBtn
}={}) => {
//实例化组件
const ComfirmInstance = new ComfirmConstructor({
data : {
isComfirm : true
}
});
ComfirmInstance.vm = ComfirmInstance.$mount();
{
//赋值外部传进来的数据
//参数定义在组件内查看
ComfirmInstance.title = title;
ComfirmInstance.content = content;
ComfirmInstance.hideTitle = Boolean(hideTitle);
ComfirmInstance.hideCancel = Boolean(hideCancel);
ComfirmInstance.btnFontSize = btnFontSize;
//显示关闭按钮
ComfirmInstance.showCloseBtn = Boolean(showCloseBtn);
if(cancelText){
ComfirmInstance.cancelText = cancelText + '';
}
if(okText){
ComfirmInstance.okText = okText + '';
}
//赋值确定按钮回调事件
if(onOk && typeof onOk === 'function'){
ComfirmInstance.onOk = onOk;
}
//取消回调事件
if(onCancel && typeof onCancel === 'function'){
ComfirmInstance.onCancel = onCancel;
}
}
// 控制组件的显隐
ComfirmInstance.modelShow = true;
//获取dom
ComfirmInstance.dom = ComfirmInstance.vm.$el;
//往body里增加弹窗
document.body.appendChild(ComfirmInstance.dom);
return ComfirmInstance.vm;
}
export default{
//导出安装的文件
install : (vue) => {
vue.prototype.$comfirm = Comfirm;
}
}
/*
使用说明
第一种方式
在main.js中引入
import Comfirm from './components/comfirm';
Vue.use(Comfirm);
在业务模块通过方法调用
this.$comfirm({
// hideTitle 是否隐藏头部,默认为false
// hideCancel 是否隐藏取消按钮,默认为false
content : '内容字符串,可以是带html结构的',
cancelText : '取消按钮文案,默认是取消',
okText : '确认按钮文案,默认是确认',
//成功回调,可以不设置
onOk(){
console.log('xixihaha ')
},
//取消回调,可以不设置
onCancel(){
console.log('取消')
}
})
第二种方式
在需要使用的页面作为组件引用
import comfirm from '../../components/common/comfirm/comfirm.vue';
<comfirm title="标题" content="内容" v-model="showComfirm"></comfirm>
value 对话框是否显示,可使用 v-model 双向绑定数据。 Boolean false
title 标题
content 内容
ok-text 确定按钮文字 String 确定
cancel-text 取消按钮文字 String 取消
on-ok 点击确定的回调
on-cancel 点击取消的回调
hide-title 隐藏标题
hide-cancel 是否隐藏取消按钮,默认为false
*/
以下是vue3的入口文件
import { createVNode, render } from 'vue';
//引入确认弹窗组件
import comfirm from './comfirm.vue';
const Comfirm = function(options:any={}){
// 判断是否已经有节点
const comfirmDom = document.getElementById('comfirm-box');
//如果有节点删除
if(comfirmDom && document.body.contains(comfirmDom)){
document.body.removeChild(comfirmDom);
}
//定义是插件形式调用
options.isComfirm = true;
//显示弹窗
options.value = true;
//创建虚拟dom
const vm:any = createVNode(comfirm,options);
const container = document.createElement('div');
container.id = 'comfirm-box';
//执行渲染函数
render(vm,container);
//往body增加节点
document.body.appendChild(container);
}
export default{
install : (app:any) => {
app.config.globalProperties.$comfirm = Comfirm;
}
}
/*
使用说明
第一种方式
在main.js中引入
import Comfirm from './components/common/comfirm';
Vue.use(Comfirm);
在业务模块通过方法调用
this.$comfirm({
// hideTitle 是否隐藏头部,默认为false
// hideCancel 是否隐藏取消按钮,默认为false
content : '内容字符串,可以是带html结构的',
cancelText : '取消按钮文案,默认是取消',
okText : '确认按钮文案,默认是确认',
//成功回调,可以不设置
onOk(){
console.log('xixihaha ')
},
//取消回调,可以不设置
onCancel(){
console.log('取消')
}
})
第二种方式
在需要使用的页面作为组件引用
import comfirm from '../../components/common/comfirm/comfirm.vue';
<comfirm title="标题" content="内容" v-model="showComfirm"></comfirm>
value 对话框是否显示,可使用 v-model 双向绑定数据。 Boolean false
title 标题
content 内容
ok-text 确定按钮文字 String 确定
cancel-text 取消按钮文字 String 取消
on-ok 点击确定的回调
on-cancel 点击取消的回调
hide-title 隐藏标题
hide-cancel 是否隐藏取消按钮,默认为false
*/
注意点
1.在vue3中的setup使用
import {getCurrentInstance} from 'vue';
setup(){
const {ctx}:any = getCurrentInstance();
ctx.$comfirm({
// hideTitle 是否隐藏头部,默认为false
// hideCancel 是否隐藏取消按钮,默认为false
content : '内容字符串,可以是带html结构的',
cancelText : '取消按钮文案,默认是取消',
okText : '确认按钮文案,默认是确认',
//成功回调,可以不设置
onOk(){
console.log('xixihaha ')
},
//取消回调,可以不设置
onCancel(){
console.log('取消')
}
});
}
网友评论