select-picker.uvue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <view class="select-picker">
  3. <view class="select-item" :class="{'no-margin': !showLabel}">
  4. <text class="select-label" v-if="showLabel && label.length > 0" :style="{ width: labelWidth }">{{ label }}</text>
  5. <view class="select-input-box" @click="showPicker = true">
  6. <text class="select-input-text" :class="{'placeholder': modelValue.length == 0}">{{ displayText }}</text>
  7. <view class="select-input-icons">
  8. <image v-if="clearable && modelValue.length > 0" class="select-input-clear" src="/static/images/common/2.png" mode="aspectFit" @click.stop="handleClear"></image>
  9. <image class="select-input-arrow" src="/static/images/common/1.png" mode="aspectFit"></image>
  10. </view>
  11. </view>
  12. </view>
  13. <!-- 选择器弹窗 -->
  14. <l-popup v-model="showPicker" position="bottom">
  15. <l-picker
  16. cancel-btn="取消"
  17. confirm-btn="确定"
  18. :title="title"
  19. title-style="font-size: 32rpx; font-weight: 500; color: #000000;"
  20. cancel-style="font-size: 32rpx; color: #888888;"
  21. confirm-style="font-size: 32rpx; color: #1890ff;"
  22. @cancel="showPicker = false"
  23. @confirm="handleConfirm">
  24. <l-picker-item :options="options"></l-picker-item>
  25. </l-picker>
  26. </l-popup>
  27. </view>
  28. </template>
  29. <script setup lang="uts">
  30. import { ref, computed } from 'vue'
  31. import type { PickerColumn, PickerConfirmEvent } from '@/uni_modules/lime-picker'
  32. // Props 定义
  33. type Props = {
  34. modelValue: string
  35. label?: string
  36. placeholder?: string
  37. title?: string
  38. options: PickerColumn
  39. labelWidth?: string
  40. showLabel?: boolean
  41. clearable?: boolean
  42. }
  43. const props = withDefaults(defineProps<Props>(), {
  44. label: '',
  45. placeholder: '请选择',
  46. title: '请选择',
  47. labelWidth: '140rpx',
  48. showLabel: true,
  49. clearable: true
  50. })
  51. // Emits 定义
  52. const emit = defineEmits<{
  53. (e: 'update:modelValue', value: string): void
  54. }>()
  55. // 弹窗显示状态
  56. const showPicker = ref<boolean>(false)
  57. // 显示文本
  58. const displayText = computed<string>(() => {
  59. return props.modelValue.length > 0 ? props.modelValue : props.placeholder
  60. })
  61. // 确认选择
  62. const handleConfirm = (e: PickerConfirmEvent): void => {
  63. if (e.values.length > 0) {
  64. emit('update:modelValue', e.values[0] as string)
  65. }
  66. showPicker.value = false
  67. }
  68. // 清除选择
  69. const handleClear = (): void => {
  70. emit('update:modelValue', '')
  71. }
  72. </script>
  73. <style lang="scss">
  74. .select-picker {
  75. .select-item {
  76. display: flex;
  77. flex-direction: row;
  78. align-items: center;
  79. margin-bottom: 24rpx;
  80. &.no-margin {
  81. margin-bottom: 0;
  82. }
  83. .select-label {
  84. display: flex;
  85. align-items: center;
  86. justify-content: flex-start;
  87. font-weight: 400;
  88. font-size: 28rpx;
  89. color: #6e7580;
  90. }
  91. .select-input-box {
  92. flex: 1;
  93. display: flex;
  94. flex-direction: row;
  95. align-items: center;
  96. justify-content: space-between;
  97. padding: 20rpx;
  98. background-color: #f5f7fa;
  99. border-radius: 8rpx;
  100. .select-input-text {
  101. font-weight: 400;
  102. font-size: 28rpx;
  103. color: #131415;
  104. flex: 1;
  105. &.placeholder {
  106. color: #999999;
  107. }
  108. }
  109. .select-input-icons {
  110. display: flex;
  111. flex-direction: row;
  112. align-items: center;
  113. margin-left: 20rpx;
  114. .select-input-clear {
  115. width: 28rpx;
  116. height: 28rpx;
  117. margin-right: 12rpx;
  118. }
  119. .select-input-arrow {
  120. width: 24rpx;
  121. height: 24rpx;
  122. }
  123. }
  124. }
  125. }
  126. }
  127. </style>