BusinessScopeSelectorContent.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <template>
  2. <div class="selector-content" v-if="selectorType === 'card'" key="s-content">
  3. 暂不提供业务范围的card组件
  4. </div>
  5. <div class="selector-content" :class="{ 'no-more': !showMore }" v-else-if="selectorType === 'line'" key="s-content">
  6. <span class="action-button show-more" @click="showMore = !showMore" v-if="needShowMore">
  7. <span class="action-text">{{ showMore ? '收起' : '更多' }}</span>
  8. <span class="el-icon-arrow-down" :class="showMore ? 'rotate180' : ''"></span>
  9. </span>
  10. <div class="select-group-container">
  11. <div
  12. v-for="(item, index) in bScopeList"
  13. :key="index"
  14. class="j-button-item bgc hover"
  15. :class="{
  16. active: item.selected,
  17. all: item.name === '全部'
  18. }"
  19. @click="buttonClick(item)"
  20. >{{ item.name }}</div>
  21. </div>
  22. </div>
  23. </template>
  24. <script>
  25. export default {
  26. name: 'business-scope-selector-content',
  27. props: {
  28. selectorType: {
  29. type: String,
  30. default: 'card' // card/line
  31. },
  32. singleChoice: { // 是是否单选? 只有在selectorType=line下才会生效
  33. type: Boolean,
  34. default: false
  35. },
  36. initList: {
  37. type: Array,
  38. default () {
  39. return []
  40. }
  41. }
  42. },
  43. data () {
  44. return {
  45. needShowMore: false,
  46. showMore: false,
  47. bScopeList: [],
  48. bScopeItemExp: {
  49. name: '全部',
  50. value: '',
  51. selected: true
  52. }
  53. }
  54. },
  55. watch: {
  56. initList (newVal) {
  57. this.$nextTick(() => {
  58. this.calcNeedShowMoreOrNot()
  59. })
  60. }
  61. },
  62. created () {
  63. this.init()
  64. },
  65. mounted () {
  66. this.calcNeedShowMoreOrNot()
  67. },
  68. methods: {
  69. init () {
  70. const list = [JSON.parse(JSON.stringify(this.bScopeItemExp))]
  71. this.initList.forEach(item => {
  72. list.push({
  73. name: item,
  74. value: item,
  75. selected: false
  76. })
  77. })
  78. this.bScopeList = list
  79. },
  80. setState (data = []) {
  81. if (!Array.isArray) return
  82. if (data.length === 0) {
  83. this.bScopeList.forEach(item => (item.selected = false))
  84. this.bScopeList[0].selected = true
  85. } else {
  86. this.bScopeList[0].selected = false
  87. this.bScopeList.forEach(item => {
  88. if (data.includes(item.name)) {
  89. item.selected = true
  90. }
  91. })
  92. }
  93. },
  94. getState () {
  95. const arr = []
  96. if (this.bScopeList[0].selected) {
  97. return arr
  98. }
  99. return this.bScopeList.filter(item => item.selected).map(item => item.name)
  100. },
  101. onChange () {
  102. const state = this.getState()
  103. this.$emit('onChange', state)
  104. },
  105. buttonClick (item) {
  106. if (item.name === this.bScopeItemExp.name) {
  107. this.setState()
  108. } else {
  109. if (this.singleChoice) {
  110. this.setState()
  111. this.bScopeList[0].selected = false
  112. item.selected = !item.selected
  113. } else {
  114. this.bScopeList[0].selected = false
  115. item.selected = !item.selected
  116. // 子项全部选中则全部按钮选中,子项如果一个没有被选中,则全部按钮被选中
  117. const { allNotSelected } = this.checkAllSelectedState()
  118. if (allNotSelected) {
  119. this.setState()
  120. }
  121. }
  122. }
  123. this.onChange()
  124. },
  125. // 除了全部按钮之外的按钮的状态
  126. checkAllSelectedState () {
  127. const stateArr = []
  128. this.bScopeList.forEach(item => {
  129. if (item.name !== this.bScopeItemExp.name) {
  130. stateArr.push(item.selected)
  131. }
  132. })
  133. return {
  134. // 找不到false,就说明全部被选中
  135. allSelected: stateArr.indexOf(false) === -1,
  136. // 找不到true,就说明没有一个被选中
  137. allNotSelected: stateArr.indexOf(true) === -1
  138. }
  139. },
  140. // 计算需不需要进行展开等操作
  141. calcNeedShowMoreOrNot () {
  142. this.$nextTick(() => {
  143. let buttonListTop = []
  144. const wrapper = document.querySelector('.business-scope-selector.s-line')
  145. const container = wrapper.querySelector('.select-group-container')
  146. const buttonDOMList = container.querySelectorAll('.j-button-item')
  147. buttonDOMList.forEach(item => {
  148. buttonListTop.push(item.getBoundingClientRect().top)
  149. })
  150. // 数组去重
  151. buttonListTop = Array.from(new Set(buttonListTop))
  152. this.needShowMore = buttonListTop.length > 1
  153. })
  154. }
  155. }
  156. }
  157. </script>
  158. <style lang="scss" scoped>
  159. .s-card {}
  160. .s-line {
  161. .selector-content {
  162. position: relative;
  163. display: flex;
  164. width: 100%;
  165. &.no-more {
  166. height: 38px;
  167. overflow: hidden;
  168. flex: 1;
  169. }
  170. }
  171. .select-group-container {
  172. display: flex;
  173. padding-right: 40px;
  174. flex-wrap: wrap;
  175. }
  176. }
  177. </style>