项目:taro3 + vue3
描述:picker组件不能自定义样式,需要用picker-view和picker-view-colum组合 , 存在的一些坑
效果图
<view class="base-picker">
<view class="picker-bar f-b-c" @tap="onClickPicker">
<view class="label f-l-c">
<text class="txt">
{{ currentIndex > -1 ? list[currentIndex].label : '默认文字' }}
</text>
</view>
<slot></slot>
</view>
<teleport v-if="isShowPickerModal" to="#modalTeleport">
<view class="picker-modal">
<view class="cover-bg" @tap.stop="isShowPickerModal = false" />
<view class="picker-modal-in">
<view class="picker-head f-b-c">
<view class="button default-color" @tap.stop="isShowPickerModal = false"> 取消 </view>
<view class="modal-head-title">
{{ title }}
</view>
<view class="button primary-color" @tap.stop="onSubmit"> 确定 </view>
</view>
<view class="picker-body">
<picker-view
class="picker-view"
indicator-class="picker-column-item-active"
mask-style="background: transparent; z-index:0;"
:value="pickerViewValue"
:immediate-change="true"
@change="onChangePickerView">
<picker-view-column>
<view
class="picker-column-item"
:class="{'active': pickerViewValue[0] === index}"
v-for="(item, index) in list"
:key="`floor-item-${index}`">
{{ item.label }}
</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</teleport>
</view>
name: 'BasePicker',
props: {
modelValue: {
type: Number,
default: 0
},
title: {
type: String,
default: ''
},
list: {
type: Array,
default: () => ([])
}
},
emits: ['update:modelValue'],
/**
* 点击bar
*/
onClickPicker() {
const idx = this.currentIndex.value
this.pickerViewValue.value = [idx]
this.isShowPickerModal.value = true
}
/**
* 选中
* @param e
*/
onChangePickerView(e) {
// todo 区别alipay
const list = e.detail.value
this.pickerViewValue.value = list
}
/**
* 点击确定
*/
onSubmit() {
const pickerViewValue = this.pickerViewValue.value
this.isShowPickerModal.value = false
this.context.emit('update:modelValue', pickerViewValue[0])
}
watch(() => props.modelValue, newVal => {
this.currentIndex.value = newVal
}, { immediate: true })
遇到的坑:
1、默认mask是一个白色透明渐变,换成其他颜色也是一个渐变色,不能是纯色,所以这里的mask-style直接设置了透明
2、indicator-class设置的是中间选中的背景块的样式(宽高及背景),不包含选中文字的样式
3、indicator-class设置彩色后,会遮挡住选中的字
在这里插入图片描述
解决:indicator-class里面一定要加z-index:0;
4)中间选中块默认是有border的
解决:indicator-class的::before和::after设置display: none;
5)选中的文字没有办法直接设置样式,只能通过change的index去添加,但是效果不好,有卡顿,官方给出的方案是picker-view上设置immediate-change=true, 但是效果不明显
6)picker-view的change事件的结果e.detail.value是数组array[number],但是支付宝和微信是不一样的
微信:[选中的index]
支付宝:[选中的第几个]