multi-selector-picker.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <view class="multi-selector picker-item"
  3. :style="{ height: height }">
  4. <picker-view :value="pickerValue"
  5. :indicator-style="indicatorStyle"
  6. :style="{ height: height }"
  7. @change="handleChange">
  8. <picker-view-column v-for="(column, index) in pickerColumns"
  9. :key="index">
  10. <view v-for="(item, i) in column || []"
  11. :class="[
  12. 'lb-picker-column',
  13. item[props.value] === selectValue[index]
  14. ? 'lb-picker-column-active'
  15. : ''
  16. ]"
  17. :key="i"
  18. :style="{ height: columnHeight, 'line-height': columnHeight }">
  19. <view class="lb-picker-column-label">
  20. {{ item[props.label] }}
  21. </view>
  22. </view>
  23. </picker-view-column>
  24. </picker-view>
  25. </view>
  26. </template>
  27. <script>
  28. import { getIndicatorHeight } from '../utils.js'
  29. const indicatorHeight = getIndicatorHeight()
  30. export default {
  31. props: {
  32. value: Array,
  33. list: Array,
  34. props: Object,
  35. level: Number,
  36. visible: Boolean,
  37. height: String
  38. },
  39. data () {
  40. return {
  41. pickerValue: [],
  42. pickerColumns: [],
  43. selectValue: [],
  44. selectItem: [],
  45. columnHeight: indicatorHeight + 'px',
  46. indicatorStyle: `height: ${indicatorHeight}px`
  47. }
  48. },
  49. created () {
  50. this.init('init')
  51. },
  52. methods: {
  53. init (changeType) {
  54. this.setPickerItems(this.list)
  55. this.$emit('change', {
  56. value: this.selectValue,
  57. item: this.selectItem,
  58. index: this.pickerValue,
  59. change: changeType
  60. })
  61. },
  62. handleChange (item) {
  63. const pickerValue = item.detail.value
  64. const columnIndex = pickerValue.findIndex(
  65. (item, i) => item !== this.pickerValue[i]
  66. )
  67. const valueIndex = pickerValue[columnIndex]
  68. this.setPickerChange(pickerValue, valueIndex, columnIndex)
  69. },
  70. setPickerChange (pickerValue, valueIndex, columnIndex) {
  71. for (let i = 0; i < this.level; i++) {
  72. if (i > columnIndex) {
  73. pickerValue[i] = 0
  74. const column =
  75. this.pickerColumns[i - 1][valueIndex] ||
  76. this.pickerColumns[i - 1][0]
  77. this.$set(this.pickerColumns, i, column[this.props.children] || [])
  78. valueIndex = 0
  79. }
  80. this.pickerValue = pickerValue
  81. this.selectItem[i] = this.pickerColumns[i][pickerValue[i]]
  82. if (this.selectItem[i]) {
  83. this.selectValue[i] = this.selectItem[i][this.props.value]
  84. } else {
  85. const spliceNum = this.level - i
  86. this.pickerValue.splice(i, spliceNum)
  87. this.selectValue.splice(i, spliceNum)
  88. this.selectItem.splice(i, spliceNum)
  89. this.pickerColumns.splice(i, spliceNum)
  90. break
  91. }
  92. }
  93. this.$emit('change', {
  94. value: this.selectValue,
  95. item: this.selectItem,
  96. index: this.pickerValue,
  97. change: 'scroll'
  98. })
  99. },
  100. setPickerItems (list = [], index = 0) {
  101. if (!list.length) return
  102. const defaultValue = this.value || []
  103. if (index < this.level) {
  104. const value = defaultValue[index] || ''
  105. let i = list.findIndex(item => item[this.props.value] === value)
  106. i = i > -1 ? i : 0
  107. this.$set(this.pickerValue, index, i)
  108. this.$set(this.pickerColumns, index, list)
  109. if (list[i]) {
  110. this.$set(this.selectValue, index, list[i][this.props.value])
  111. this.$set(this.selectItem, index, list[i])
  112. this.setPickerItems(list[i][this.props.children] || [], index + 1)
  113. }
  114. }
  115. }
  116. },
  117. watch: {
  118. value (newVal) {
  119. this.init('value')
  120. },
  121. list () {
  122. this.init('list')
  123. }
  124. }
  125. }
  126. </script>
  127. <style lang="scss" scoped>
  128. @import "../style/picker-item.scss";
  129. </style>