index.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import baseComponent from '../helpers/baseComponent'
  2. import popupMixin from '../helpers/mixins/popupMixin'
  3. import { nextTick } from '../helpers/hooks/useNativeAPI'
  4. import { POPUP_SELECTOR, getDefaultProps, notFoundContent, getNotFoundContent, flattenOptions } from './utils'
  5. baseComponent({
  6. behaviors: [popupMixin(POPUP_SELECTOR)],
  7. properties: {
  8. prefixCls: {
  9. type: String,
  10. value: POPUP_SELECTOR.substring(1),
  11. },
  12. virtualized: {
  13. type: Boolean,
  14. value: false,
  15. },
  16. notFoundContent: {
  17. type: null,
  18. value: { ...notFoundContent },
  19. },
  20. ...getDefaultProps(),
  21. },
  22. data: {
  23. mergedOptions: [],
  24. mergedOptionsValueMap: new Map(),
  25. mergedNotFoundContent: { ...notFoundContent },
  26. },
  27. observers: {
  28. ['options, multiple'](options, multiple) {
  29. const mergedOptions = flattenOptions(options)
  30. const mergedOptionsValueMap = new Map()
  31. mergedOptions.forEach((option, index) => {
  32. mergedOptionsValueMap.set(option.value, { option, index })
  33. })
  34. this.setData({
  35. mergedOptions,
  36. mergedOptionsValueMap,
  37. })
  38. },
  39. notFoundContent(notFoundContent) {
  40. this.renderEmpty(notFoundContent)
  41. },
  42. },
  43. methods: {
  44. renderEmpty(notFoundContent) {
  45. const mergedNotFoundContent = getNotFoundContent(notFoundContent)
  46. if (this.data.mergedNotFoundContent !== mergedNotFoundContent) {
  47. this.setData({ mergedNotFoundContent })
  48. }
  49. },
  50. updated(inputValue, isForce) {
  51. if (this.hasFieldDecorator && !isForce) { return }
  52. if (this.data.inputValue !== inputValue) {
  53. this.setData({ inputValue })
  54. }
  55. },
  56. getIndexRef(props = this.data) {
  57. if (props.multiple) {
  58. const len = props.value.length
  59. if (
  60. props.value.length > 0 &&
  61. props.mergedOptionsValueMap.has(props.value[len - 1])
  62. ) {
  63. const { index } = props.mergedOptionsValueMap.get(
  64. props.value[len - 1]
  65. )
  66. return index
  67. }
  68. } else {
  69. if (
  70. props.value &&
  71. props.mergedOptionsValueMap.has(props.value)
  72. ) {
  73. const { index } = props.mergedOptionsValueMap.get(props.value)
  74. return index
  75. }
  76. }
  77. return -1
  78. },
  79. scrollToItem(index) {
  80. const menuRef = this.querySelector(POPUP_SELECTOR)
  81. if (menuRef) {
  82. menuRef.scrollToItem(index)
  83. }
  84. },
  85. onShow() {
  86. const { value } = this.data
  87. let newValue = this.data.inputValue
  88. if (newValue !== value) {
  89. newValue = value
  90. }
  91. // collect field component & forceUpdate
  92. if (this.hasFieldDecorator) {
  93. const fieldContext = this.getFieldContext()
  94. if (fieldContext) {
  95. newValue = fieldContext.data.value
  96. fieldContext.changeValue(newValue)
  97. }
  98. }
  99. if (this.data.inputValue !== newValue) {
  100. this.updated(newValue)
  101. }
  102. nextTick(() => {
  103. const index = this.getIndexRef({ ...this.data, value: newValue })
  104. if (index !== -1) {
  105. this.scrollToItem(index)
  106. }
  107. })
  108. },
  109. getPickerValue(value = this.data.inputValue) {
  110. const { virtualized, mergedOptions } = this.data
  111. const cols = virtualized ? mergedOptions : undefined
  112. this.picker = this.picker || this.querySelector(POPUP_SELECTOR)
  113. return this.picker && this.picker.getValue(value, cols)
  114. },
  115. onSelectChange(e) {
  116. if (!this.mounted) { return }
  117. const { value } = e.detail
  118. this.updated(value, true)
  119. this.triggerEvent('valueChange', this.formatPickerValue({ ...e.detail }))
  120. },
  121. },
  122. ready() {
  123. this.renderEmpty(this.data.notFoundContent)
  124. },
  125. })