DoublePicker2.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <view>
  3. <!-- 触发按钮 -->
  4. <view class="picker-trigger" @click="showPicker">
  5. <view class="picker-action">
  6. <view class="text-grey">{{ label }}</view>
  7. </view>
  8. </view>
  9. <!-- 弹出层 -->
  10. <picker
  11. mode="multiSelector"
  12. :value="pickerValue"
  13. :range="pickerRange"
  14. @change="PickerChange"
  15. @columnchange="PickerColumnChange"
  16. :show="show"
  17. >
  18. <view class="picker-content">
  19. <view class="picker-column">{{ pickerRange[0][pickerValue[0]][rangeKey] }}</view>
  20. <view class="picker-column">{{ pickerRange[1][pickerValue[1]][rangeKey] }}</view>
  21. </view>
  22. </picker>
  23. </view>
  24. </template>
  25. <script>
  26. export default {
  27. data() {
  28. return {
  29. show: false, // 控制选择器的显示
  30. pickerValue: [0, 0], // 两列的默认选中索引
  31. pickerRange: [[], []], // 两列数据
  32. label: '请选择', // 显示的标签
  33. };
  34. },
  35. props: {
  36. value: {
  37. type: Array,
  38. default: () => [null, null] // 两列的绑定值
  39. },
  40. empty: {
  41. type: String,
  42. default: ''
  43. },
  44. rangeKey: {
  45. type: String,
  46. default: 'label'
  47. },
  48. rangeValue: {
  49. type: String,
  50. default: 'value'
  51. },
  52. range1: {
  53. type: Array,
  54. default: () => []
  55. },
  56. range2: {
  57. type: Array,
  58. default: () => []
  59. },
  60. disabled: {
  61. type: Boolean,
  62. default: false
  63. },
  64. onChangeNew: {
  65. type: Function,
  66. default: null,
  67. }
  68. },
  69. watch: {
  70. range1: {
  71. handler(newRange) {
  72. this.pickerRange[0] = newRange;
  73. },
  74. immediate: true
  75. },
  76. range2: {
  77. handler(newRange) {
  78. this.pickerRange[1] = newRange;
  79. },
  80. immediate: true
  81. },
  82. value: {
  83. handler(newVal) {
  84. if (newVal && newVal.length === 2) {
  85. const [val1, val2] = newVal;
  86. this.label = `${this.findLabel(this.pickerRange[0], val1)} - ${this.findLabel(this.pickerRange[1], val2)}`;
  87. }
  88. },
  89. immediate: true
  90. }
  91. },
  92. methods: {
  93. showPicker() {
  94. if (!this.disabled) {
  95. this.show = true;
  96. }
  97. },
  98. PickerChange(e) {
  99. const [index1, index2] = e.detail.value;
  100. const value1 = this.pickerRange[0][index1][this.rangeValue];
  101. const value2 = this.pickerRange[1][index2][this.rangeValue];
  102. this.label = `${this.pickerRange[0][index1][this.rangeKey]} - ${this.pickerRange[1][index2][this.rangeKey]}`;
  103. this.$emit('input', [value1, value2]);
  104. this.show = false; // 关闭选择器
  105. if (this.onChangeNew) {
  106. this.onChangeNew();
  107. }
  108. },
  109. PickerColumnChange(e) {
  110. const { column, value } = e.detail;
  111. this.pickerValue[column] = value;
  112. },
  113. findLabel(range, value) {
  114. const option = range.find(item => item[this.rangeValue] === value);
  115. return option ? option[this.rangeKey] : '请选择';
  116. }
  117. },
  118. mounted() {
  119. if (this.empty) {
  120. this.label = this.empty;
  121. }
  122. this.pickerRange = [this.range1, this.range2];
  123. }
  124. };
  125. </script>
  126. <style>
  127. .picker-trigger {
  128. padding: 10px;
  129. border: 1px solid #ccc;
  130. border-radius: 4px;
  131. background-color: #fff;
  132. display: flex;
  133. align-items: center;
  134. }
  135. .text-grey {
  136. color: #999;
  137. margin-left: 8px;
  138. }
  139. </style>