uni-app picker-view 中的@pickend,@pickstart,immediate-change希望可以做到全端支持
uni-app picker-view 中的@pickend,@pickstart,immediate-change希望可以做到全端支持
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | win11 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
HBuilderX类型:正式
HBuilderX版本号:4.27
手机系统:Android
手机系统版本号:Android 15
手机厂商:华为
手机机型:16161616161
页面类型:vue
vue版本:vue2
打包方式:云端
App下载地址或H5网址:z
示例代码:
<template>
<uni-popup
ref="popupRef"
is-mask-click="false"
@maskClick="onCancel"
type="bottom"
>
<view class="custom-picker-popup">
<view class="page-header">
<view class="page-header-content-text">{{ title }}</view>
<view class="close-icon" @click="onCancel">
<custom-icon
icon="/static/images/psychological-test/icon-closelist@2x.png"
size="24rpx"
/>
</view>
</view>
<view class="page-content">
<picker-view
value="[insideSelectedIndex]"
@change="onPickerViewChange"
indicator-style="height: 112rpx"
class="picker-view"
>
<picker-view-column>
<view
class="picker-view-item"
v-for="(item, index)
key="index"
>
{{ item.label }}
</view>
</picker-view-column>
</picker-view>
</view>
<view class="page-footer">
<button @click="onOk">确定</button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue'
const emit = defineEmits([
'update:visible',
'update:selectedValue',
'change',
'ok',
'cancel',
])
const props = defineProps({
title: {
type: String,
default: '',
},
visible: {
type: Boolean,
default: false,
},
selectedValue: {
type: [String, Number],
default: 0,
},
options: {
type: Array,
default: () => [],
},
isRow: {
type: Boolean,
default: false,
},
})
const popupRef = ref()
const insideVisible = ref(false)
const insideSelectedIndex = ref(undefined)
const findSelectedIndex = (value) => {
const resIndex = props.options.findIndex((item) => item.value === value)
return resIndex > -1 ? resIndex : 0
}
watch(
[() => props.visible],
([newval]) => {
console.log('props: ', props)
insideVisible.value = newval
},
{ immediate: true }
)
watch(
[() => insideVisible.value],
([newval]) => {
if (!popupRef.value) return
if (newval) open()
else close()
})
watch(
[() => props.selectedValue],
([newval]) => {
insideSelectedIndex.value = findSelectedIndex(newval)
},
{ immediate: true }
)
watch(
[() => insideSelectedIndex.value],
([newval]) => {
emit('update:selectedValue', props.options[newval].value)
emit('change', props.options[newval].value)
})
const computedSelectedValue = () => {
const row = props.options[insideSelectedIndex.value]
const res = props.isRow ? row : row?.value
return res
}
const onPickerViewChange = (e) => {
const val = e.detail.value
insideSelectedIndex.value = val[0]
}
const open = () => {
popupRef.value.open()
}
const close = () => {
popupRef.value.close()
}
const onOk = () => {
emit('ok', computedSelectedValue())
}
const onCancel = () => {
emit('cancel')
}
</script>
<style lang="scss" scoped>
.custom-picker-popup {
border-radius: 36rpx 36rpx 0rpx 0rpx;
padding: 28rpx 0 0 0;
background-color: #fff;
.page-header {
position: relative;
margin: 0 34rpx 56rpx;
display: flex;
align-items: center;
.page-header-content-text {
margin: 0 auto;
display: flex;
flex-wrap: wrap;
font-size: 36rpx;
color: #131313;
}
.close-icon {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 34rpx;
display: flex;
}
}
.page-content {
margin-bottom: 26rpx;
height: 508rpx;
.picker-view {
height: 508rpx;
.picker-view-item {
display: flex;
justify-content: center;
align-items: center;
font-size: 36rpx;
}
}
}
.page-footer {
margin: 0 32rpx;
padding-bottom: 20rpx;
button {
border: none;
height: 88rpx;
background: linear-gradient(90deg, #957ffe 0%, #bf9be8 100%);
border-radius: 44rpx 44rpx 44rpx 44rpx;
font-size: 32rpx;
color: #ffffff;
}
}
}
</style>
操作步骤:
picker-view 中的[@pickend](/user/pickend),[@pickstart](/user/pickstart),immediate-change希望可以做到全端支持,当在弹窗中使用这个组件时,由于app端不支持这个属性,拿不到动画开始时的状态,导致弹窗关闭时picker-view的onchange事件没有触发
预期结果:
picker-view 中的[@pickend](/user/pickend),[@pickstart](/user/pickstart),immediate-change希望可以做到全端支持
实际结果:
picker-view 中的[@pickend](/user/pickend),[@pickstart](/user/pickstart),immediate-change希望可以做到全端支持,当在弹窗中使用这个组件时,由于app端不支持这个属性,拿不到动画开始时的状态,导致弹窗关闭时picker-view的onchange事件没有触发
bug描述:
picker-view 中的[@pickend](/user/pickend),[@pickstart](/user/pickstart),immediate-change希望可以做到全端支持,当在弹窗中使用这个组件时,由于app端不支持这个属性,拿不到动画开始时的状态,导致弹窗关闭时picker-view的onchange事件没有触发
`
官方的这个组件,就是因为更新不及时问题,我们都自己写了一个picker
在uni-app中,picker-view
组件提供了日期和时间选择器等功能,同时支持自定义选择器。@pickend
和@pickstart
事件分别用于监听选择结束和开始的事件,而immediate-change
属性决定了用户选择时是否立即触发change
事件。为了确保这些功能全端支持(包括H5、小程序、App等平台),我们可以利用uni-app提供的跨平台能力来编写代码。
以下是一个简单的代码示例,展示了如何在uni-app中使用picker-view
组件,并处理@pickend
、@pickstart
事件以及immediate-change
属性:
<template>
<view>
<picker-view :value="pickerValue" @change="onPickerChange" @pickstart="onPickStart" @pickend="onPickEnd" :immediate-change="immediateChange">
<picker-view-column>
<view v-for="(item, index) in columns[0]" :key="index">{{ item }}</view>
</picker-view-column>
<picker-view-column>
<view v-for="(item, index) in columns[1]" :key="index">{{ item }}</view>
</picker-view-column>
<!-- 可以根据需要添加更多列 -->
</picker-view>
<button @click="changePickerValue">Change Picker Value Programmatically</button>
</view>
</template>
<script>
export default {
data() {
return {
pickerValue: [0, 0], // 初始选择的值
columns: [
['Column 1-1', 'Column 1-2', 'Column 1-3'],
['Column 2-1', 'Column 2-2', 'Column 2-3']
],
immediateChange: true // 是否立即触发change事件
};
},
methods: {
onPickerChange(e) {
console.log('Picker changed:', e.detail.value);
this.pickerValue = e.detail.value;
},
onPickStart() {
console.log('Picker start picking');
},
onPickEnd() {
console.log('Picker end picking');
},
changePickerValue() {
this.pickerValue = [1, 1]; // 例如,将选择的值改为第二行第二列
}
}
};
</script>
<style scoped>
/* 添加样式以适应不同平台 */
</style>
在这个示例中,我们定义了一个包含两列的picker-view
,并绑定了@change
、@pickstart
和@pickend
事件。immediate-change
属性被设置为true
,表示选择时会立即触发change
事件。此外,还提供了一个按钮用于程序化地改变picker-view
的值。
由于uni-app的跨平台能力,上述代码应该能够在H5、小程序、App等平台上正常运行,前提是这些平台已经正确配置了uni-app的运行环境。