index.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import baseComponent from '../helpers/baseComponent'
  2. import eventsMixin from '../helpers/mixins/eventsMixin'
  3. import { nextTick } from '../helpers/hooks/useNativeAPI'
  4. import * as common from '../helpers/wxs/common'
  5. import { props } from './props'
  6. const fieldNames = { lable: 'title', value: 'value' }
  7. const getOptions = (options) => common.getOptions(options, fieldNames)
  8. baseComponent({
  9. useField: true,
  10. behaviors: [eventsMixin()],
  11. relations: {
  12. '../field/index': {
  13. type: 'ancestor',
  14. },
  15. '../radio/index': {
  16. type: 'descendant',
  17. observer() {
  18. this.callDebounceFn(this.changeValue)
  19. },
  20. },
  21. },
  22. properties: props,
  23. data: {
  24. fieldNames,
  25. inputValue: '',
  26. keys: [],
  27. },
  28. observers: {
  29. value(newVal) {
  30. if (this.hasFieldDecorator) return
  31. this.updated(newVal)
  32. this.changeValue({ value: newVal })
  33. },
  34. inputValue(newVal) {
  35. if (this.hasFieldDecorator) {
  36. this.changeValue({ value: newVal })
  37. }
  38. },
  39. ['options, disabled, readOnly, hasLine, withListComponent, iconPosition, iconSize, iconOn, iconOff, prefixCls'](...args) {
  40. const [
  41. options,
  42. disabled,
  43. readOnly,
  44. hasLine,
  45. withListComponent,
  46. iconPosition,
  47. iconSize,
  48. iconOn,
  49. iconOff,
  50. prefixCls,
  51. ] = args
  52. this.changeValue({
  53. value: this.data.inputValue,
  54. options,
  55. disabled,
  56. readOnly,
  57. hasLine,
  58. withListComponent,
  59. iconPosition,
  60. iconSize,
  61. iconOn,
  62. iconOff,
  63. prefixCls,
  64. })
  65. },
  66. },
  67. methods: {
  68. updated(inputValue) {
  69. if (this.data.inputValue !== inputValue) {
  70. this.setData({ inputValue })
  71. }
  72. },
  73. changeValue(props = {}) {
  74. const {
  75. value,
  76. options,
  77. disabled,
  78. readOnly,
  79. hasLine,
  80. withListComponent,
  81. iconPosition,
  82. iconSize,
  83. iconOn,
  84. iconOff,
  85. prefixCls,
  86. } = {
  87. ...this.data,
  88. value: this.data.inputValue,
  89. ...props,
  90. }
  91. const showOptions = getOptions(options)
  92. const setChildrenValues = (children) => {
  93. const keys = []
  94. if (children && children.length > 0) {
  95. const lastIndex = children.length - 1
  96. children.forEach((child, index) => {
  97. const active = value === child.data.value
  98. const isLast = index === lastIndex
  99. const useDefaultSize = iconSize === ''
  100. const useDefaultIcon = iconOn === '' && iconOff === ''
  101. child.changeValue(active, index, isLast, {
  102. disabled,
  103. readOnly,
  104. hasLine,
  105. // 如果使用 <Field /> 组件包裹时,子组件的 hasLine 属性无效
  106. hasFieldDecorator: !!this.hasFieldDecorator,
  107. withListComponent,
  108. iconPosition,
  109. iconSize: withListComponent
  110. ? iconSize : useDefaultSize
  111. ? '23' : iconSize,
  112. iconOn: withListComponent
  113. ? iconOn : useDefaultIcon
  114. ? 'success' : iconOn,
  115. iconOff: withListComponent
  116. ? (iconOff || iconOn) : useDefaultIcon
  117. ? 'circle' : iconOff,
  118. })
  119. keys.push(child.data)
  120. })
  121. }
  122. if (this.data.keys !== keys) {
  123. this.setData({
  124. keys,
  125. })
  126. }
  127. }
  128. nextTick(() => {
  129. const elements = showOptions.length > 0
  130. ? this.querySelectorAll(`.${prefixCls}__radio`)
  131. : this.getRelationsByName('../radio/index')
  132. setChildrenValues(elements)
  133. })
  134. },
  135. onChange(item) {
  136. this.triggerEvent('change', {
  137. ...item,
  138. ...this.getValue(item.value),
  139. name: this.data.name,
  140. value: item.value, // 兼容 3.6.1 之前版本,不改变 value
  141. })
  142. },
  143. onRadioChange(e) {
  144. // Set real index
  145. const { index } = e.currentTarget.dataset
  146. this.onChange({ ...e.detail, index })
  147. },
  148. getValue(value = this.data.inputValue, cols = this.data.keys) {
  149. const newValue = value ? [value] : []
  150. const checkedValues = cols.filter((option) => newValue.includes(option.value))
  151. const displayValue = checkedValues.map((option) => option.title) || []
  152. const allValues = cols.map((option) => option.value)
  153. const selectedIndex = newValue.map((n) => allValues.indexOf(n))
  154. return {
  155. value,
  156. displayValue: displayValue[0] != null ? displayValue[0] : '',
  157. selectedIndex: selectedIndex[0] != null ? selectedIndex[0] : -1,
  158. selectedValue: value,
  159. cols,
  160. }
  161. },
  162. getBoundingClientRect(callback) {
  163. this.cellGroup = this.cellGroup || this.querySelector('#wux-cell-group')
  164. return this.cellGroup && this.cellGroup.getBoundingClientRect(callback)
  165. },
  166. },
  167. })