阅读 360

uniapp 打造自用组件库 (四) 下沉式对话框

uniapp 打造自用组件库 (四) 下沉式对话框

前言

本文将带领读者使用uniapp封装一些常用组件,方便日后开发时重复使用,当然文中封装的组件不可能适配所有应用场景,但是我希望读者可以跟着我的思路实现出来,然后可以在此基础上优化改进为自己合适的,本人一个前端小菜鸡,希望大佬们可以不吝赐教,也是对我的技术水平的提升

下沉式对话框

需求

前段时间,魅族发布了新的Flyme9,其中使用的一些新的组件风格非常友好,例如本文中实现的下沉式对话框,将对话框位置下沉到底部,方便大屏用户单手操作,并且动画优美,于是就用Uniapp实现了一个自用的,跨端表现效果良好,并且支持下滑关闭

image.png

效果展示

应用效果

image.png

应用代码
 <button type="default" @tap="isShow = true" >案例 退出登录</button> <Ydialog :show.sync="isShow" @change='change'> <view slot='title'> 退出登录 </view> </Ydialog> 复制代码

export default { data() { return { isShow:false, } }, methods: { change(type){ if(type == 'confirm'){ uni.showToast({ title:'退出登录成功' }) return } }, } } 复制代码

实现思路

首先制作一个蒙版放在最底层,然后上方放置view 为对话框 对话框中分为上下两部分,一部分放置提示信息,另一部分放置按钮,通过sync动态修改show,同时监听蒙版点击事件,监听对话框滑动事件,实现点击空白处,向下划动收起对话框,同时触发取消事件

完整实现代码

<template> <view class="make" @touchmove.stop.prevent @tap.stop="hidePopup" v-if="myshow" :style="{backgroundColor:client != '100%'?'rgba(0,0,0,0.3)':'rgba(0,0,0,0)'}"> <view class="popup" :style="{transform:client != '100%'?'translateY('+client+'px)':'translateY(100%)',transition:!isTouch?'0.4s ease,transform 0.2s ease':'0.4s ease,transform 0s ease'}"> <view class="box" @tap.stop @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"> <view class="title"> <slot name="title"> </slot> </view> <view class="btns"> <view @tap="tap('cancel')"> <slot name="cancel"> 取消 </slot> </view> <view style="margin-left: 30rpx;" @tap="tap('confirm')"> <slot name="confirm"> 确定 </slot> </view> </view> </view> </view> </view> </template> <script> export default { data() { return { myshow: false, clientY: 0, client: '100%', ismake: false, defaultNum: 0, isTouch: false }; }, props: { show: { type: Boolean, default: false } }, watch: { show() { if (this.show) { this.myshow = true setTimeout(() => { this.client = 0 this.defaultNum = 0 }, 100) } else { this.hidePopup() } } }, methods: { touchstart({ touches }) { this.isTouch = true this.clientY = touches[0].clientY return }, touchmove({ touches }) { if (this.defaultNum == 0) { let num = (touches[0].clientY - this.clientY) + 0 if (num > 0) { this.client = num } } return }, touchend(end) { this.isTouch = false if (this.defaultNum == 0) { if (this.client >= 50) { this.hidePopup() } else { this.client = 0 this.defaultNum = 0 } } return }, tap(type) { this.$emit('change', type) this.$emit('update:show', false) }, hidePopup() { this.client = '100%' setTimeout(() => { this.$emit('update:show', false) this.myshow = false }, 200) }, } } </script> <style lang="scss" scoped> .make { position: fixed; width: 100%; height: 100%; bottom: 0; right: 0; background-color: rgba(0, 0, 0, 1); transition: 0.2s; // background: linear-gradient(0deg, rgba(0, 0, 0, 0.2) 50%, rgba(0, 0, 0, 0) 90%); z-index: 9999; .popup { position: absolute; bottom: 0; height: 100%; width: 100%; display: flex; z-index: 9999; flex-direction: column; border-radius: 50rpx 50rpx 0 0; overflow: hidden; justify-content: flex-end; .box { margin: 60rpx 30rpx; border-radius: 30rpx; background-color: #fff; display: flex; flex-direction: column; .title { display: flex; justify-content: center; padding: 30rpx; font-size: 16px; font-weight: bold; } .btns { display: flex; padding: 30rpx; view { flex: 1; text-align: center; border-radius: 20rpx; padding: 25rpx 30rpx; background-color: #F9F9F9; color: #0f7ffc; font-weight: bold; &:active { background-color: #f2f2f2; } } } } } } </style>


作者:shengtu_归尘
链接:https://juejin.cn/post/7023295252853178398


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐