自研组件<十九> 自定义picker组件 可以自定义背景/选中高亮文字

项目:taro3 + vue3

描述:picker组件不能自定义样式,需要用picker-view和picker-view-colum组合 , 存在的一些坑

效果图
自研组件<十九> 自定义picker组件 可以自定义背景/选中高亮文字_第1张图片

<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设置彩色后,会遮挡住选中的字
自研组件<十九> 自定义picker组件 可以自定义背景/选中高亮文字_第2张图片
解决:indicator-class里面一定要加z-index:0;

4)中间选中块默认是有border的
自研组件<十九> 自定义picker组件 可以自定义背景/选中高亮文字_第3张图片
解决:indicator-class的::before和::after设置display: none;

5)选中的文字没有办法直接设置样式,只能通过change的index去添加,但是效果不好,有卡顿,官方给出的方案是picker-view上设置immediate-change=true, 但是效果不明显

6)picker-view的change事件的结果e.detail.value是数组array[number],但是支付宝和微信是不一样的
微信:[选中的index]
支付宝:[选中的第几个]

你可能感兴趣的:(小程序,#,Taro,1024程序员节,自定义picker,小程序)