index.js 6.0 KB

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