skyouc
2024-12-21 c9c263dc43ad90f95f24a036cee9e6b47afb596c
uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
@@ -1,147 +1,147 @@
<template>
   <view class="uni-collapse">
      <slot />
   </view>
</template>
<script>
   /**
    * Collapse 折叠面板
    * @description 展示可以折叠 / 展开的内容区域
    * @tutorial https://ext.dcloud.net.cn/plugin?id=23
    * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
    * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
    * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
    */
   export default {
      name: 'uniCollapse',
      emits:['change','activeItem','input','update:modelValue'],
      props: {
         value: {
            type: [String, Array],
            default: ''
         },
         modelValue: {
            type: [String, Array],
            default: ''
         },
         accordion: {
            // 是否开启手风琴效果
            type: [Boolean, String],
            default: false
         },
      },
      data() {
         return {}
      },
      computed: {
         // TODO 兼容 vue2 和 vue3
         dataValue() {
            let value = (typeof this.value === 'string' && this.value === '') ||
               (Array.isArray(this.value) && this.value.length === 0)
            let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
               (Array.isArray(this.modelValue) && this.modelValue.length === 0)
            if (value) {
               return this.modelValue
            }
            if (modelValue) {
               return this.value
            }
            return this.value
         }
      },
      watch: {
         dataValue(val) {
            this.setOpen(val)
         }
      },
      created() {
         this.childrens = []
         this.names = []
      },
      mounted() {
         this.$nextTick(()=>{
            this.setOpen(this.dataValue)
         })
      },
      methods: {
         setOpen(val) {
            let str = typeof val === 'string'
            let arr = Array.isArray(val)
            this.childrens.forEach((vm, index) => {
               if (str) {
                  if (val === vm.nameSync) {
                     if (!this.accordion) {
                        console.warn('accordion 属性为 false ,v-model 类型应该为 array')
                        return
                     }
                     vm.isOpen = true
                  }
               }
               if (arr) {
                  val.forEach(v => {
                     if (v === vm.nameSync) {
                        if (this.accordion) {
                           console.warn('accordion 属性为 true ,v-model 类型应该为 string')
                           return
                        }
                        vm.isOpen = true
                     }
                  })
               }
            })
            this.emit(val)
         },
         setAccordion(self) {
            if (!this.accordion) return
            this.childrens.forEach((vm, index) => {
               if (self !== vm) {
                  vm.isOpen = false
               }
            })
         },
         resize() {
            this.childrens.forEach((vm, index) => {
               // #ifndef APP-NVUE
               vm.getCollapseHeight()
               // #endif
               // #ifdef APP-NVUE
               vm.getNvueHwight()
               // #endif
            })
         },
         onChange(isOpen, self) {
            let activeItem = []
            if (this.accordion) {
               activeItem = isOpen ? self.nameSync : ''
            } else {
               this.childrens.forEach((vm, index) => {
                  if (vm.isOpen) {
                     activeItem.push(vm.nameSync)
                  }
               })
            }
            this.$emit('change', activeItem)
            this.emit(activeItem)
         },
         emit(val){
            this.$emit('input', val)
            this.$emit('update:modelValue', val)
         }
      }
   }
</script>
<style lang="scss" >
   .uni-collapse {
      /* #ifndef APP-NVUE */
      width: 100%;
      display: flex;
      /* #endif */
      /* #ifdef APP-NVUE */
      flex: 1;
      /* #endif */
      flex-direction: column;
      background-color: #fff;
   }
</style>
<template>
   <view class="uni-collapse">
      <slot />
   </view>
</template>
<script>
   /**
    * Collapse 折叠面板
    * @description 展示可以折叠 / 展开的内容区域
    * @tutorial https://ext.dcloud.net.cn/plugin?id=23
    * @property {String|Array} value 当前激活面板改变时触发(如果是手风琴模式,参数类型为string,否则为array)
    * @property {Boolean} accordion = [true|false] 是否开启手风琴效果是否开启手风琴效果
    * @event {Function} change 切换面板时触发,如果是手风琴模式,返回类型为string,否则为array
    */
   export default {
      name: 'uniCollapse',
      emits:['change','activeItem','input','update:modelValue'],
      props: {
         value: {
            type: [String, Array],
            default: ''
         },
         modelValue: {
            type: [String, Array],
            default: ''
         },
         accordion: {
            // 是否开启手风琴效果
            type: [Boolean, String],
            default: false
         },
      },
      data() {
         return {}
      },
      computed: {
         // TODO 兼容 vue2 和 vue3
         dataValue() {
            let value = (typeof this.value === 'string' && this.value === '') ||
               (Array.isArray(this.value) && this.value.length === 0)
            let modelValue = (typeof this.modelValue === 'string' && this.modelValue === '') ||
               (Array.isArray(this.modelValue) && this.modelValue.length === 0)
            if (value) {
               return this.modelValue
            }
            if (modelValue) {
               return this.value
            }
            return this.value
         }
      },
      watch: {
         dataValue(val) {
            this.setOpen(val)
         }
      },
      created() {
         this.childrens = []
         this.names = []
      },
      mounted() {
         this.$nextTick(()=>{
            this.setOpen(this.dataValue)
         })
      },
      methods: {
         setOpen(val) {
            let str = typeof val === 'string'
            let arr = Array.isArray(val)
            this.childrens.forEach((vm, index) => {
               if (str) {
                  if (val === vm.nameSync) {
                     if (!this.accordion) {
                        console.warn('accordion 属性为 false ,v-model 类型应该为 array')
                        return
                     }
                     vm.isOpen = true
                  }
               }
               if (arr) {
                  val.forEach(v => {
                     if (v === vm.nameSync) {
                        if (this.accordion) {
                           console.warn('accordion 属性为 true ,v-model 类型应该为 string')
                           return
                        }
                        vm.isOpen = true
                     }
                  })
               }
            })
            this.emit(val)
         },
         setAccordion(self) {
            if (!this.accordion) return
            this.childrens.forEach((vm, index) => {
               if (self !== vm) {
                  vm.isOpen = false
               }
            })
         },
         resize() {
            this.childrens.forEach((vm, index) => {
               // #ifndef APP-NVUE
               vm.getCollapseHeight()
               // #endif
               // #ifdef APP-NVUE
               vm.getNvueHwight()
               // #endif
            })
         },
         onChange(isOpen, self) {
            let activeItem = []
            if (this.accordion) {
               activeItem = isOpen ? self.nameSync : ''
            } else {
               this.childrens.forEach((vm, index) => {
                  if (vm.isOpen) {
                     activeItem.push(vm.nameSync)
                  }
               })
            }
            this.$emit('change', activeItem)
            this.emit(activeItem)
         },
         emit(val){
            this.$emit('input', val)
            this.$emit('update:modelValue', val)
         }
      }
   }
</script>
<style lang="scss" >
   .uni-collapse {
      /* #ifndef APP-NVUE */
      width: 100%;
      display: flex;
      /* #endif */
      /* #ifdef APP-NVUE */
      flex: 1;
      /* #endif */
      flex-direction: column;
      background-color: #fff;
   }
</style>