uniapp项目开发中,关于使用uni-popup组件跨组件关闭打开的问题实现解决思路。
项目开发中,在tabBar页面引用了封装好的用来展示列表数据的子组件,该子组件中包含了uni-ui中的uni-popup弹出层组件。当popup弹出层打开时,切换tabBar页面的时候,popup并不会被关闭。期望的结果是:切换tabBar页面,popup关闭。
官网文档中,示例如下:
<template> <view> <button @click="open">打开弹窗</button> <uni-popup ref="popup" type="bottom">底部弹出 Popup</uni-popup> </view> </template> <script> export default { methods:{ open(){ // 通过组件定义的ref调用uni-popup方法 ,如果传入参数 ,type 属性将失效 ,仅支持 ['top','left','bottom','right','center'] this.$refs.popup.open('top') } } } </script>
项目中的代码(子组件):handleToScratch函数中,将open与close传值给父组件,由父组件选择调用,如下:
<template> <view class="wrap"> <view class="single" v-for="(item, index) in list" :key="index"> <view class="mask"></view> <view class="mask2"></view> <view class="line"></view> <view class="content"> <view class="first"> <text>{{ item.score }}元</text> </view> <view class="second"> <view class="second_title"> <text>{{ item.scoreType | calScoreType }}</text> </view> </view> <view class="three" @click="handleToScratch(item)"></view> </view> </view> <!-- 普通弹窗 --> <uni-popup ref="popup"> <view class="popup-content"> <view><text class="title">请选择兑换期号</text></view> <uni-data-checkbox selectedColor="#FF6600" v-model="radio1" :localdata="selectList" @change="changeCheckbox"></uni-data-checkbox> </view> </uni-popup> </view> </template> <script> export default { props: { list: { type: Array, default() { return []; } }, selectList: { type: Array, default() { return []; } } }, data() { return { radio1: '' //默认选择的号码 }; }, filters: { calScoreType(newValue) { if (newValue === 1) { return 'xx兑换券'; } else if (newValue === 2) { return 'xx兑换券'; } } }, watch: { radio1(val) { console.log(val, 'val'); } }, methods: { changeCheckbox(e) { if (e.detail.data.orderCount >= e.detail.data.maxOrderCount) { uni.showModal({ content: '您选择的本期暂无余票,请选择其它日期的票!', showCancel: false }); return; } if (Date.parse(new Date()) < Date.parse(e.detail.data.startSellTime)) { uni.showModal({ content: '您选择的还没有到选号时间,请在每月8号进行选号!', showCancel: false }); return; } if (Date.parse(new Date()) >= Date.parse(e.detail.data.endSellTime)) { uni.showModal({ content: '您选择的已经截止选号,请在每月的8号选号!', showCancel: false }); return; } this.$refs.popup.close(); uni.navigateTo({ url: `/subpages1/bet/bet?type=3&score=${e.detail.data.score}&issueNo=${e.detail.data.text}&issueId=${e.detail.value}&openingTime=${e.detail.data.openingTime}` }); this.$nextTick(() => { this.radio1 = ''; }); }, handleToScratch(item) { let _open = this.$refs.popup.open; let _close = this.$refs.popup.close; this.$emit('handleUp', item, _open, _close); } } }; </script> <style lang="scss" scoped> .wrap { width: 100%; padding: 24rpx 24rpx; box-sizing: border-box; .single { width: 100%; height: 164rpx; background-color: #ff6600; border-radius: 20rpx; position: relative; overflow: hidden; margin-bottom: 20rpx; .mask { background-color: #f3f3f3; border-radius: 50%; width: 40rpx; height: 40rpx; position: absolute; left: 498rpx; top: -20rpx; } .mask2 { background-color: #f3f3f3; border-radius: 50%; width: 40rpx; height: 40rpx; position: absolute; left: 498rpx; bottom: -20rpx; } .line { width: 4rpx; height: 102rpx; background-color: #fff; position: absolute; left: 518rpx; top: 32rpx; } .content { width: 100%; height: inherit; box-sizing: border-box; padding: 0 32rpx 0 54rpx; display: flex; justify-content: space-between; .first { flex: 1; display: flex; justify-content: center; align-items: center; color: #ffffff; font-size: 38rpx; font-weight: bold; } .second { flex: 3; display: flex; padding-left: 30rpx; box-sizing: border-box; flex-direction: column; justify-content: center; align-items: flex-start; .second_title { font-size: 24rpx; color: #fff; margin-bottom: 14rpx; } .second_time { font-size: 20rpx; color: #fff; } } .three { background: url(../../static/personal_pic/exchange_button.png) no-repeat center / contain; flex: 1; } } } .popup-content { display: flex; flex-direction: column; justify-content: space-between; align-items: center; padding: 26rpx; height: auto; background-color: #fff; border-radius: 32rpx; .title { width: 100%; text-align: center; line-height: 70rpx; font-size: 30rpx; } } } </style>
父组件(tabBar页面)中使用,本例中,父组件使用了mixins,下面代码中,handleUp方法由子组件触发,解决方法就是将popup的open与close存起来传递给父组件,由父组件在合适的时机调用
import { getHomeEquities, selectIssue } from '@/request/api.js'; import { mapState } from 'vuex'; export const getEquities = { data() { return { list: [], selectlist: [], _close: null }; }, computed: { ...mapState('User', ['userId', 'phoneNumber']) }, onl oad() { this.getHomeEquitiesData() }, onHide() { this._close && this._close() }, onPullDownRefresh() { this.getHomeEquitiesData() setTimeout(()=>{ uni.stopPullDownRefresh() }, 1000) }, methods: { getHomeEquitiesData() { uni.showLoading({ title: '数据加载中...' }) getHomeEquities(this.phoneNumber, this.userId) .then(res => { uni.hideLoading() if (res.data.code === 200) { if (res.data.data && res.data.data.length) { this.list = res.data.data; } else { uni.showToast({ title: '暂无权益数据!', icon: 'none' }); } } else if (res.data.code === 500) { uni.showToast({ title: res.data.msg, icon: 'none' }); } }) .catch(err => { console.log(err); }); }, handleUp(item, _open, _close) { this._close = _close if (item.scoreType === 1) { _open('center'); selectIssue(1).then(res => { if (res.data.code === 200) { this.selectlist = res.data.data.map(item2 => { return { text: item2.issueNo, value: item2.issueId, lotteryKind: item2.lotteryKind, lotteryKindId: item2.lotteryKindId, maxOrderCount: item2.maxOrderCount, orderCount: item2.orderCount, startSellTime: item2.startSellTime, endSellTime: item2.endSellTime, openingTime: item2.openingTime, score: item.score }; }); } }); } else if (item.scoreType === 2) { uni.showModal({ title: '提示', content: '确认订阅资讯月刊吗?', success: res => { if (res.confirm) { uni.navigateTo({ url: '/pages/home/monthly/monthly' }); } else if (res.cancel) {} } }); } } } }
标签:uniapp,popup,res,close,组件,uni,data From: https://www.cnblogs.com/mmdt/p/16921955.html