uni-app picker-view 中的@pickend,@pickstart,immediate-change希望可以做到全端支持

发布于 1周前 作者 sinazl 来自 Uni-App

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事件没有触发
`

2 回复

官方的这个组件,就是因为更新不及时问题,我们都自己写了一个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的运行环境。

回到顶部