微信小程序封装公共弹窗dailog组件-UNIAPP篇
在小程序的开发过程中,会发现弹框这东西使用频率太高了,能不能封装一个公共组件呢~ 答案当然是能!!! 开发思路借鉴了一下vant,有兴趣的同学可以,研究一下
在小程序的开发过程中,会发现弹框这东西使用频率太高了,能不能封装一个公共组件呢~ 答案当然是能!!!
开发思路借鉴了一下vant,有兴趣的同学可以,研究一下 https://github.com/youzan/vant-weapp/tree/dev/dist/dialog
大概思路通过selectComponent获取到组件,然后传入对应参数,
代码实现
创建dialog.js
const Dialog = (options) => {
return new Promise((resolve, reject) => {
const pages = getCurrentPages();
const getContext = pages[pages.length - 1];
let dialog = getContext.selectComponent("#e-dialog").$vm;
if (dialog) {
//dialog.show(config);
options.callback = (action, instance) => {
action === "confirm" ? resolve(instance) : reject(instance);
};
dialog.show(options);
} else {
console.warn("未找到 e-dialog 节点,请确认 selector 及 context 是否正确");
}
});
};
Dialog.alert = (options) => Dialog(options);
Dialog.confirm = (options) => Dialog(Object.assign({ showCancelButton: true }, options));
export default Dialog;
dialog.vue
<template>
<!--dialog-modal-->
<view class="dialog-modal" :class="[modalVisible ? 'show' : '']">
<view class="flex">
<view class="box" :animation="animationData">
<view class="modal-title">
{{ configData.title }}
</view>
<view :class="`${configData.className} modal-desc`">
<block v-if="configData.isHtml">
<view class="text-html">
<rich-text :nodes="configData.content"></rich-text>
</view>
</block>
<block v-else>
<text class="text">{{ configData.content }}</text>
</block>
</view>
<view class="modal-btn" :class="[configData.showCancelButton == false ? 'wid100' : '']">
<block v-if="configData.showCancelButton">
<button class="btn" @click="onCancel">{{ configData.cancelText }}</button>
</block>
<button class="confirm btn" @click="onConfirm">{{ configData.confirmText }}</button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, watch, getCurrentInstance, nextTick } from "vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "提示",
},
content: {
type: String,
default: "",
},
className: {
type: String,
default: "text-center",
},
isHtml: {
type: Boolean,
default: false,
},
showCancelButton: {
type: Boolean,
default: false,
},
cancelText: {
type: String,
default: "取消",
},
confirmText: {
type: String,
default: "确定",
},
});
const instance = getCurrentInstance();
const callback = ref(() => {});
const modalVisible = ref(false);
const configData = ref(props);
const animation = uni.createAnimation({
duration: 200,
timingFunction: "ease",
});
const animationData = ref(null);
watch(
() => props.visible,
(newProps) => {
if (newProps == true) {
setTimeout(() => {
modalVisible.value = true;
animation.scale(1).opacity(1).step();
animationData.value = animation.export();
}, 100);
} else {
modalVisible.value = false;
}
},
{ immediate: true }
);
const emit = defineEmits(["cancel", "confirm"]);
const onCancel = function () {
handleAction("cancel");
// animation.scale(0).opacity(0).step();
// animationData.value = animation.export();
// setTimeout(() => {
// emit("cancel");
// }, 100);
};
const onConfirm = function () {
handleAction("confirm");
// animation.scale(0).opacity(0).step();
// animationData.value = animation.export();
// setTimeout(() => {
// emit("ok");
// }, 100);
};
const show = (data) => {
callback.value = !data.callback ? () => {} : data.callback;
modalVisible.value = true;
animation.scale(1).opacity(1).step();
animationData.value = animation.export();
configData.value = Object.assign(
{},
{
title: data.title ?? "提示",
content: data.content ?? "",
cancelText: data.cancelText ?? "取消",
confirmText: data.confirmText ?? "确定",
showCancelButton: data.showCancelButton ?? false,
isHtml: data.isHtml ?? false,
className: data.className ?? "text-center",
}
);
};
const handleAction = (action) => {
emit(action, instance);
closeDailog(action);
};
const closeDailog = (action) => {
modalVisible.value = false;
animation.scale(0).opacity(0).step();
animationData.value = animation.export();
setTimeout(function () {
nextTick(() => {
if (callback.value) {
callback.value(action, instance);
}
});
}, 100);
};
defineExpose({
show,
});
</script>
<style lang="less" scoped>
.dialog-modal {
position: fixed;
background-color: rgba(0, 0, 0, 0.5);
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
z-index: 3;
.flex {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.box {
background-color: #ffffff;
border-radius: 20rpx;
padding: 40rpx;
width: 65%;
text-align: center;
font-size: 28rpx;
transform: scale(0);
opacity: 0;
.modal-title {
font-size: 32rpx;
font-weight: bold;
color: var(--zpyj-text-main-color);
}
.modal-desc {
margin: 30rpx 0;
.text {
display: block;
line-height: 44rpx;
color: #666666;
font-size: 28rpx;
}
.text-html {
line-height: 44rpx;
}
&.text-left {
text-align: left;
}
&.text-center {
text-align: center;
}
}
.modal-btn {
display: flex;
align-items: center;
justify-content: space-between;
.btn {
all: unset;
width: 220rpx;
line-height: 88rpx;
display: block;
background-color: #ebf5ff;
border-radius: 10rpx;
border-color: #ebf5ff;
font-size: 32rpx;
margin: 0;
color: #008aff;
position: relative;
&.confirm {
background-color: #008aff;
border-color: #008aff;
color: #fff;
}
}
&.wid100 {
width: 100%;
.btn {
width: 100%;
}
}
}
}
}
&.show {
opacity: 1;
visibility: inherit;
}
}
</style>
使用
<Dailog id="e-dialog"></Dailog>
import Dailog from "@/components/Dailog";
DailogClass.alert({ content: "提示信息" }).then(() => {
//点击确定按钮
});
DailogClass.confirm({ content: "提示信息" }).then(() => {
//点击确定按钮
}).catch(error => {
//点击取消按钮
});
微信小程序原生和uniapp 的开发思路是一致的,只是需要吧uniapp 的语法改成微信小程序原生的写法即可
以上这篇微信小程序封装公共弹窗dailog组件-UNIAPP篇就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持芦苇派。
原创文章,作者:ECHO陈文,如若转载,请注明出处:https://www.luweipai.cn/html/1709262685/