uni-collapse.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <view class="uni-collapse">
  3. <slot />
  4. </view>
  5. </template>
  6. <script>
  7. /**
  8. * Collapse 折叠面板
  9. * @description 展示可以折叠 / 展开的内容区域
  10. * @tutorial https://ext.dcloud.net.cn/plugin?id=23
  11. * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
  12. * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
  13. * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
  14. */
  15. export default {
  16. name: 'uniCollapse',
  17. emits:['change','activeItem','input','update:modelValue'],
  18. props: {
  19. value: {
  20. type: [String, Array],
  21. default: ''
  22. },
  23. modelValue: {
  24. type: [String, Array],
  25. default: ''
  26. },
  27. accordion: {
  28. // 是否开启手风琴效果
  29. type: [Boolean, String],
  30. default: false
  31. },
  32. },
  33. data() {
  34. return {}
  35. },
  36. computed: {
  37. // TODO 兼容 vue2 和 vue3
  38. dataValue() {
  39. let value = (typeof this.value === 'string' && this.value === '') ||
  40. (Array.isArray(this.value) && this.value.length === 0)
  41. let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
  42. (Array.isArray(this.modelValue) && this.modelValue.length === 0)
  43. if (value) {
  44. return this.modelValue
  45. }
  46. if (modelValue) {
  47. return this.value
  48. }
  49. return this.value
  50. }
  51. },
  52. watch: {
  53. dataValue(val) {
  54. this.setOpen(val)
  55. }
  56. },
  57. created() {
  58. this.childrens = []
  59. this.names = []
  60. },
  61. mounted() {
  62. this.setOpen(this.dataValue)
  63. },
  64. methods: {
  65. setOpen(val) {
  66. let str = typeof val === 'string'
  67. let arr = Array.isArray(val)
  68. this.childrens.forEach((vm, index) => {
  69. if (str) {
  70. if (val === vm.nameSync) {
  71. if (!this.accordion) {
  72. console.warn('accordion 属性为 false ,v-model 类型应该为 array')
  73. return
  74. }
  75. vm.isOpen = true
  76. }
  77. }
  78. if (arr) {
  79. val.forEach(v => {
  80. if (v === vm.nameSync) {
  81. if (this.accordion) {
  82. console.warn('accordion 属性为 true ,v-model 类型应该为 string')
  83. return
  84. }
  85. vm.isOpen = true
  86. }
  87. })
  88. }
  89. })
  90. this.emit(val)
  91. },
  92. setAccordion(self) {
  93. if (!this.accordion) return
  94. this.childrens.forEach((vm, index) => {
  95. if (self !== vm) {
  96. vm.isOpen = false
  97. }
  98. })
  99. },
  100. resize() {
  101. this.childrens.forEach((vm, index) => {
  102. // #ifndef APP-NVUE
  103. vm.getCollapseHeight()
  104. // #endif
  105. // #ifdef APP-NVUE
  106. vm.getNvueHwight()
  107. // #endif
  108. })
  109. },
  110. onChange(isOpen, self) {
  111. let activeItem = []
  112. if (this.accordion) {
  113. activeItem = isOpen ? self.nameSync : ''
  114. } else {
  115. this.childrens.forEach((vm, index) => {
  116. if (vm.isOpen) {
  117. activeItem.push(vm.nameSync)
  118. }
  119. })
  120. }
  121. this.$emit('change', activeItem)
  122. this.emit(activeItem)
  123. },
  124. emit(val){
  125. this.$emit('input', val)
  126. this.$emit('update:modelValue', val)
  127. }
  128. }
  129. }
  130. </script>
  131. <style lang="scss" >
  132. .uni-collapse {
  133. /* #ifndef APP-NVUE */
  134. width: 100%;
  135. display: flex;
  136. /* #endif */
  137. /* #ifdef APP-NVUE */
  138. flex: 1;
  139. /* #endif */
  140. flex-direction: column;
  141. background-color: #fff;
  142. }
  143. </style>