点击自定义封装的组件触发uni-popup组件从手机底部弹起
- 发布:2021-10-14 21:51
- 更新:2021-10-14 21:54
- 阅读:413
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: Windows 10 家庭中文版20H2,64 位操作系统, 基于 x64 的处理器
HBuilderX类型: 正式
HBuilderX版本号: 3.2.9
手机系统: Android
手机系统版本号: Android 10
手机厂商: 华为
手机机型: HLK-AL00
页面类型: vue
打包方式: 云端
项目创建方式: HBuilderX
操作步骤:
预期结果:
从手机底部弹起,最高层级,点击蒙蔽收起底部弹窗
从手机底部弹起,最高层级,点击蒙蔽收起底部弹窗
实际结果:
只有蒙蔽,弹窗内容添加在页面下方, 跟随页面滚动
只有蒙蔽,弹窗内容添加在页面下方, 跟随页面滚动
bug描述:
组件内的uni-popup 组件出问题, 没有从手机底部弹起, 而是自己加在页面后面, 跟随页面滚动, 自身的定位没有相对于手机窗口
8***@qq.com (作者)
// 调用页面
<template>
<KXDateTime @rundata='kxdatetimeend' :end="endDate" :default="'date'"></KXDateTime>
</template>
// ------------------
// 组件内容
<template>
<view name='KXDateTime'>
<view :class="dir == 'right' ? 'list-row change dir-right' : 'list-row change'" @click="open">
<view class="hint">
{{changeDate == 0 ? '请选择' : changeDate}}
</view>
<view class="iconfont icon-xiangyou1"></view>
</view>
<uni-popup ref="popup" type="bottom">
<view class="but">
<text @click="close">取消</text>
<text @click="ok">确定</text>
</view>
<picker-view v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange">
<picker-view-column>
<view class="item" v-for="(item,index) in years" :key="index">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in months" :key="index">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in days" :key="index">{{item}}日</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in hours" :key="index">{{item}}时</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in mins" :key="index">{{item}}分</view>
</picker-view-column>
</picker-view>
<picker-view v-else :indicator-style="indicatorStyle" :value="value" @change="bindChange">
<picker-view-column>
<view class="item" v-for="(item,index) in years" :key="index">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in months" :key="index">{{item}}月</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in days" :key="index">{{item}}日</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in hours_num" :key="index">{{item}}号</view>
</picker-view-column>
</picker-view>
</uni-popup>
</view>
</template>
<script>
import uniPopup from '../uni-popup/uni-popup.vue'
export default {
name: 'KXDateTime',
components: {
uniPopup
},
props: {
isVisible: {
type: Boolean,
default: true
},
dir: '',
date: '',
start: '',
end: '',
default: '',
placeholder: ''
},
data() {
let defaultvalue = this.default;
let value = [9999, 99, 99, 0, 0];
if (defaultvalue == 'end') {
value = [9999, 99, 99, 0, 0]
} else if (defaultvalue == 'start') {
value = [0, 0, 0, 0, 0]
}
return {
isChange: false,
flang: true,
changeDate: 0,
title: 'picker-view',
years: [],
year: '',
months: [],
month: '',
days: [],
day: '',
hours: [],
hour: '',
mins: [],
min: '',
hour_num: '',
hours_num: [],
value,
valueStr: '',
visible: true,
strYMDHM: '',
indicatorStyle: `height: 80rpx;`,
trimer: null,
}
},
destroyed() {
this.flang = true;
},
methods: {
slep(slep) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(true)
}, slep)
})
},
async toData() {
console.log('change')
if (this.default == 'date') {
let tempDate = new Date();
let y = tempDate.getFullYear();
let m = tempDate.getMonth();
let d = tempDate.getDate();
let temp = this.years.findIndex(item => item == y);
let temp2 = this.months.findIndex(item => item == m);
let temp3 = this.days.findIndex(item => item == d);
this.value = [temp, temp2 + 1, temp3, 0, 0];
this.bindChange({
detail: {
value: [temp, temp2 + 1, temp3, 0, 0]
}
})
if(temp3 == -1 || temp == -1 || temp2 == -1) {
await this.slep(100);
this.toData();
}
}
},
open() {
let start;
if (this.start) {
start = this.start.replace(/-/g, "/")
start = new Date(start);
} else {
start = new Date(0);
}
let starty = start.getFullYear(); //开始年份
let end;
if (this.end) {
end = this.end.replace(/-/g, "/")
end = new Date(end);
} else {
end = new Date();
}
if (start > end) {
uni.showToast({
title: '时间范围错误!',
icon: 'none',
duration: 2000
});
return false
}
this.$forceUpdate();
if (this.valueStr) {
this.value = JSON.parse(this.valueStr);
setTimeout(() => {
this.amend();
this.toData();
}, 100)
this.$refs.popup.open()
} else {
setTimeout(() => {
this.amend();
this.toData();
}, 100)
this.$refs.popup.open()
}
let temp = [];
for (var i = 0, len = 100; i <= len; i++) {
temp.push(i)
}
this.hours_num = temp;
},
close() {
this.$refs.popup.close()
},
ok() {
let day = this.day < 10 ? '0' + this.day : this.day,
month = this.month < 10 ? '0' + this.month : this.month,
hour = this.hour < 10 ? '0' + this.hour : this.hour,
min = this.min < 10 ? '0' + this.min : this.min
if (!this.isVisible) {
hour = this.hour_num < 10 ? '0' + this.hour_num : this.hour_num
var data_ = this.year + ',' + month + ',' + day + ',' + hour
this.changeDate = this.isChange ? data_ : this.end;
this.$emit("update:number", data_)
this.$refs.popup.close()
return false;
}
let data = this.isChange ? this.year + '-' + month + '-' + day + ' ' + hour + ':' + min : this.end;
this.changeDate = this.isChange ? data : this.end;
this.$emit("rundata", data)
this.$emit("update:model", data)
this.$emit("update:model_ss", data + ':00')
this.$refs.popup.close()
},
bindChange: function(e) {
this.isChange = true;
let val = e.detail.value
this.valueStr = JSON.stringify(val);
this.year = this.years[val[0]]
this.month = this.months[val[1]]
this.day = this.days[val[2]]
this.hour = this.hours[val[3]];
this.hour_num = this.hours_num[val[3]];
this.min = this.mins[val[4]]
},
//数据校正
amend() {
if (this.valueStr) {
let val = JSON.parse(this.valueStr);
this.year = this.years[val[0]]
this.month = this.months[val[1]]
this.day = this.days[val[2]]
this.hour = this.hours[val[3]]
this.min = this.mins[val[4]]
}
let start;
if (this.start) {
start = this.start.replace(/-/g, "/")
start = new Date(start);
} else {
start = new Date(0);
}
let starty = start.getFullYear(); //开始年份
let startm = start.getMonth() + 1; //开始月份
let startd = start.getDate(); //开始天
let starth = start.getHours(); //开始小时
let startmin = start.getMinutes(); //开始分钟
let end;
if (this.end) {
end = this.end.replace(/-/g, "/")
end = new Date(end);
} else {
end = new Date();
}
let endy = end.getFullYear(); //终止年份
let endm = end.getMonth() + 1; //终止月份
let endd = end.getDate(); //终止天
let endh = end.getHours(); //终止小时
let endmin = end.getMinutes(); //终止分钟
//如果选择起始年份
let years = [],
months = [],
days = [],
hours = [],
mins = [];
let month31 = [1, 3, 5, 7, 8, 10, 12],
month30 = [4, 6, 9, 11];
let daysNum;
for (let i = starty; i <= endy; i++) {
years.push(i)
}
if (month31.indexOf(this.month) > -1) {
daysNum = 31
} else if (month30.indexOf(this.month) > -1) {
daysNum = 30
} else {
if (this.year % 4 == 0) {
daysNum = 29
} else {
daysNum = 28
}
}
let defaultvalue = this.default;
let defaulty = endy,
defaultm = endm,
defaultd = endd,
defaulth = endh,
defaultmin = endmin;
if (defaultvalue == 'end') {
defaulty = endy;
defaultm = endm;
defaultd = endd;
defaulth = endh;
defaultmin = endmin;
} else if (defaultvalue == 'start') {
defaulty = starty;
defaultm = startm;
defaultd = startd;
defaulth = starth;
defaultmin = startmin;
}
//当数值异常是设施默认
if (!this.year) {
this.year = defaulty
}
if (!this.month) {
this.month = defaultm
}
if (!this.day) {
this.day = defaultd
}
if (!this.hour && this.hour !== 0) {
this.hour = defaulth
}
if (!this.min && this.min !== 0) {
this.min = defaultmin
}
//判断年份是在起始年
if (this.year == starty) {
//判断起始年份和终止年份是否相等
if (starty == endy) {
//如果等,那么月份取两者中间
for (let i = startm; i <= endm; i++) {
months.push(i)
}
//判断月份是在起始月
if (this.month == startm) {
//判断起始月和终止月是否相等
if (startm == endm) {
//如果等,那么天数取两者中间
for (let i = startd; i <= endd; i++) {
days.push(i)
}
//判断日是在起始日
if (this.day == startd) {
//判断起始ri和终止日是否相等
if (startd == endd) {
//如果等,那么小时取两者中间
for (let i = starth; i <= endh; i++) {
hours.push(i)
}
//判断小时是在起始小时
if (this.hour == starth) {
//判断起始和终止是否相等
if (starth == endh) {
//如果等,那么分钟取两者中间
for (let i = startmin; i <= endmin; i++) {
mins.push(i)
}
} else {
//如果不等,到59
for (let i = startmin; i <= 59; i++) {
mins.push(i)
}
}
} else {
//判断小时是否在截止小时
if (this.hour == endh) {
//终止小时取到截止分钟
for (let i = 0; i <= endmin; i++) {
mins.push(i)
}
}
}
} else {
//如果不等,到23小时
for (let i = starth; i <= 23; i++) {
hours.push(i)
}
//判断小时是在起始小时
if (this.hour == starth) {
for (let i = startmin; i <= 59; i++) {
mins.push(i)
}
}
}
} else {
//判断日是否在截止日
if (this.day == endd) {
//终止日取到截止小时
for (let i = 0; i <= endh; i++) {
hours.push(i)
}
//判断小时是否在截止小时
if (this.hour == endh) {
//终止小时取到截止分钟
for (let i = 0; i <= endmin; i++) {
mins.push(i)
}
}
}
}
} else {
//如果不等,
for (let i = startd; i <= daysNum; i++) {
days.push(i)
}
if (this.day == startd) {
for (let i = starth; i <= 23; i++) {
hours.push(i)
}
//判断小时是在起始小时
if (this.hour == starth) {
for (let i = startmin; i <= 59; i++) {
mins.push(i)
}
}
}
}
} else {
//判断月份是在终止月
if (this.month == endm) {
//终止月取到截止天
for (let i = 1; i <= endd; i++) {
days.push(i)
}
//判断日是否在截止日
if (this.day == endd) {
//终止日取到截止小时
for (let i = 0; i <= endh; i++) {
hours.push(i)
}
//判断小时是否在截止小时
if (this.hour == endh) {
//终止小时取到截止分钟
for (let i = 0; i <= endmin; i++) {
mins.push(i)
}
}
}
}
}
} else {
//如果不等,去开始到12月份
for (let i = startm; i <= 12; i++) {
months.push(i)
}
//判断月份是在起始月
if (this.month == startm) {
//是,取天数之后
for (let i = startd; i <= daysNum; i++) {
days.push(i)
}
//判断日是在起始日
if (this.day == startd) {
//是,qu起始小时之后
for (let i = starth; i <= 23; i++) {
hours.push(i)
}
//判断小时是在起始小时
if (this.hour == starth) {
//是,qu起始分钟之后
for (let i = startmin; i <= 59; i++) {
mins.push(i)
}
}
}
}
}
} else if (this.year == endy) {
//年份中终止年
//月份取到终止月
for (let i = 1; i <= endm; i++) {
months.push(i)
}
//判断月份是在终止月
if (this.month == endm) {
//终止月取到截止天
for (let i = 1; i <= endd; i++) {
days.push(i)
}
//判断日是否在截止日
if (this.day == endd) {
//终止日取到截止小时
for (let i = 0; i <= endh; i++) {
hours.push(i)
}
//判断小时是否在截止小时
if (this.hour == endh) {
//终止小时取到截止分钟
for (let i = 0; i <= endmin; i++) {
mins.push(i)
}
}
}
}
} else {
for (let i = 1; i <= 12; i++) {
months.push(i)
}
for (let i = 1; i <= daysNum; i++) {
days.push(i)
}
for (let i = 0; i <= 23; i++) {
hours.push(i)
}
for (let i = 0; i <= 59; i++) {
mins.push(i)
}
}
if (months.length == 0) {
for (let i = 1; i <= 12; i++) {
months.push(i)
}
}
if (days.length == 0) {
for (let i = 1; i <= daysNum; i++) {
days.push(i)
}
}
if (hours.length == 0) {
for (let i = 0; i <= 23; i++) {
hours.push(i)
}
}
if (mins.length == 0) {
for (let i = 0; i <= 59; i++) {
mins.push(i)
}
}
this.years = years;
this.months = months;
this.days = days;
this.hours = hours;
this.mins = mins;
this.$forceUpdate();
}
},
watch: {
isVisible: {
handler(val) {
this.visible = val;
},
immediate: true
},
year(val) {
console.log(val)
this.amend();
},
month() {
this.amend();
},
day() {
this.amend();
},
hour() {
this.amend();
},
min() {
this.amend();
// if(this.flang){
// this.toData();
// }
// this.flang = false;
},
years(n, m) {
if (n.toString() != m.toString()) {
this.amend();
}
},
months(n, m) {
if (n.toString() != m.toString()) {
this.amend();
}
},
days(n, m) {
if (n.toString() != m.toString()) {
this.amend();
}
},
hours(n, m) {
if (n.toString() != m.toString()) {
this.amend();
}
},
mins(n, m) {
if (n.toString() != m.toString()) {
this.amend();
}
}
}
}
</script>
<style lang="scss" scoped>
text {
display: inline-block;
color: $uni-text-color-grey;
}
.item {
display: flex;
align-items: center;
justify-content: center;
}
.change {
display: flex;
justify-content: space-between;
margin-top: 24rpx;
.hint {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #8F9399;
line-height: 40rpx;
}
.iconfont {
display: flex;
align-items: center;
color: #606265;
font-size: 26rpx;
}
&.dir-right {
flex: 1;
margin-top: 0;
justify-content: flex-end;
}
}
.but {
background: #fff;
height: 80rpx;
line-height: 80rpx;
padding: 0 30rpx;
border-bottom: 1px solid #f0f0f0;
text-align: left;
text {
display: inline-block;
}
text:last-child {
float: right;
color: $uni-color-primary;
}
}
picker-view {
width: 100%;
background: #fff;
height: 600rpx;
text-align: center;
}
</style>