木灵鱼儿
阅读:214
封装一个dialog弹窗组件
需求
看了半天uniapp官方提供的插件,发现就是没有dialog弹窗的封装,有点难受,这个弹窗其实用的地方还挺多的, 但是uni-popup
组件的用法实在是有点粗暴啊,需要通过ref获取popup组件实例,操作组件实例的open和close方法实现开关,和我们日常的v-model绑定差了好多,于是自己想着造一个。
在网页端我们watch监听props的变量,然后在nextTick会调中使用popup组件实例是没有问题的,但是在微信小程序中发现这个方法有一个问题?
如果我这个弹窗默认就是true打开的状态,那么在watch中即便使用了nextTick我们也无法获取到组件的实例,这个不知道是不是bug,反正我的解决办法就是在弹窗的首次处理时在onMounted
钩子下处理。
代码
<template>
<uni-popup ref="popup" type="center" :mask-click="false" background-color="transparent" @maskClick="onMaskClick">
<view class="customer-service-dialog">xsadasxx</view>
</uni-popup>
</template>
<script lang="ts">
import { defineComponent, ref, computed, watch, nextTick, onMounted } from "vue";
export default defineComponent({
props: {
/** 是否显示弹窗 */
show: {
type: Boolean,
required: true,
},
/** 是否允许点击遮罩层关闭弹窗 */
maskClosable: {
type: Boolean,
default: true,
},
},
emits: ["update:show"],
setup(props, { emit }) {
/** 是否初始化
* 由于在微信小程序中watch的监听即便使用了nextTick也会在onMounted之前执行
* 此时通过ref获取的popup还是undefined
* 所以需要通过此变量来判断是否初始化
*/
let init = false;
const popup = ref<Popup>();
/** 遮罩层点击事件 */
function onMaskClick() {
if (props.maskClosable) {
emit("update:show", false);
}
}
/** 监听是否显示 */
watch(
() => props.show,
(val) => {
if (!init) return;
if (val) {
nextTick(() => {
popup.value?.open();
});
} else {
popup.value?.close();
}
}
);
onMounted(() => {
init = true;
if (props.show) {
popup.value?.open();
}
});
return {
popup,
onMaskClick,
};
},
});
</script>
<style scoped></style>
在外部使用的时候我们就可以通过双向绑定的方式实现弹窗的展示了。
<CustomerServiceDialog v-model:show="openCustomerServiceDialog" />
组件名这些就不多说了,写过vue的应该都知道。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

相关推荐
关于element Tooltip组件与 Drawer和Dialog这种带遮罩层的冲突问题
问题当通过Tooltip组件,click事件触发抽屉或者弹窗功能时,Tooltip的hover效果,会在抽屉和弹窗功能关闭后又再次触发显示。bug图解决思路我估计是因为遮罩层的问题,导致元素的事件监听不到鼠标离开,导致关闭弹窗后,浏览器又自动选中了。所以我的解决办法很简单,找到那个触发hover效果的dom元素,对他进行离开事件触发即可。<el-tooltip effect="dark" content="通知" placement="bottom"> <a href="javascr...

关于element的dialog垂直居中的完美解决方案
element的dialog弹窗,默认不是垂直居中的,只是水平居中,但是他有一个很好的地方,就是当窗口的高度小于dialog的高度时,他会有滚动条,并且可以完整的显示dialog,算是一个非常不错的兼容方式。但是当我们对dialog进行css调整为垂直居中时,往往会使用下面两种样式:绝对定位:.el-dialog__wrapper { position: relative; .el-dialog { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -...
杰哥
Google Chrome Windows 10杰哥,也开始uni-app了吗?
加入光荣的进化~
木灵鱼儿
FireFox Windows 10嗐,时势造英雄