148 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <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>
 |