yunshangxie/tuniao-ui/components/tn-collapse-item/tn-collapse-item.vue

237 lines
5.6 KiB
Vue
Raw Permalink Normal View History

2023-12-25 17:56:30 +08:00
<template>
<view class="tn-collapse-item-class tn-collapse-item" :style="[itemStyle]">
<!-- 头部 -->
<view
class="tn-collapse-item__head"
:style="[headStyle]"
:hover-stay-time="200"
:hover-class="hoverClass"
@tap.stop="headClick"
>
<block v-if="!$slots['title-all'] || !$slots['$title-all']">
<view
v-if="!$slots.title || !$slots.$title"
class="tn-collapse-item__head__title tn-text-ellipsis"
:style="[
{ textAlign: align ? align : 'left'},
isShow && activeStyle && !arrow ? activeStyle : ''
]"
>{{ title }}</view>
<view v-else>
<slot name="title"></slot>
</view>
<view class="tn-collapse-item__head__icon__wrap">
<view
v-if="arrow"
class="tn-icon-down tn-collapse-item__head__icon__arrow"
:class="{'tn-collapse-item__head__icon__arrow--active': isShow}"
:style="[arrowIconStyle]"
></view>
</view>
</block>
<view v-else>
<slot name="title-all"></slot>
</view>
</view>
<!-- 内容 -->
<view
class="tn-collapse-item__body"
:style="[{
height: isShow ? height + 'px' : '0'
}]"
>
<view class="tn-collapse-item__body__content" :id="elId" :style="[bodyStyle]">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'tn-collapse-item',
props: {
// 展开
open: {
type: Boolean,
default: false
},
// 唯一标识
name: {
type: String,
default: ''
},
// 标题
title: {
type: String,
default: ''
},
// 标题对齐方式
align: {
type: String,
default: 'left'
},
// 点击不收起
disabled: {
type: Boolean,
default: false
},
// 活动时样式
activeStyle: {
type: Object,
default() {
return {}
}
},
// 标识
index: {
type: [Number, String],
default: ''
}
},
computed: {
arrowIconStyle() {
let style = {}
if (this.arrowColor) {
style.color = this.arrowColor
}
return style
}
},
data() {
return {
isShow: false,
elId: this.$tn.uuid(),
// body高度
height: 0,
// 头部样式
headStyle: {},
// 主体样式
bodyStyle: {},
// item样式
itemStyle: {},
// 显示右边箭头
arrow: true,
// 箭头颜色
arrowColor: '',
// 点击头部时的效果样式
hoverClass: ''
}
},
watch: {
open(value) {
this.isShow = value
}
},
created() {
this.parent = false
this.isShow = this.open
},
mounted() {
this.init()
},
methods: {
// 异步获取内容或者修改了内容时重新获取内容的信息
init() {
this.parent = this.$tn.$parent.call(this, 'tn-collapse')
if (this.parent) {
this.nameSync = this.name ? this.name : this.parent.childrens.length
// 不存在才添加对应实例
!this.parent.childrens.includes(this) && this.parent.childrens.push(this)
this.headStyle = this.parent.headStyle
this.bodyStyle = this.parent.bodyStyle
this.itemStyle = this.parent.itemStyle
this.arrow = this.parent.arrow
this.arrowColor = this.parent.arrowColor
this.hoverClass = this.parent.hoverClass
}
this.$nextTick(() => {
this.queryRect()
})
},
// 点击头部
headClick() {
if (this.disabled) return
if (this.parent && this.parent.accordion) {
this.parent.childrens.map(child => {
// 如果是手风琴模式将其他的item关闭
if (this !== child) {
child.isShow = false
}
})
}
this.isShow = !this.isShow
// 触发修改事件
this.$emit('change', {
index: this.index,
show: this.isShow
})
// 只有在打开时才触发父元素的change
if (this.isShow) this.parent && this.parent.onChange()
this.$forceUpdate()
},
// 查询内容高度
queryRect() {
this._tGetRect('#'+this.elId).then(res => {
this.height = res.height
})
}
}
}
</script>
<style lang="scss" scoped>
.tn-collapse-item {
&__head {
position: relative;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
color: $tn-font-color;
font-size: 30rpx;
line-height: 1;
padding: 24rpx 0;
padding-left: 24rpx;
text-align: left;
background-color: #FFFFFF;
&__title {
flex: 1;
overflow: hidden;
}
&__icon {
&__arrow {
transition: all 0.3s;
margin-right: 20rpx;
margin-left: 14rpx;
font-size: inherit;
&--active {
transform: rotate(180deg);
transform-origin: center center;
}
}
}
}
&__body {
transition: all 0.3s;
overflow: hidden;
&__content {
overflow: hidden;
font-size: 28rpx;
color: $tn-font-color;
text-align: left;
background-color: #FFFFFF;
padding-left: 24rpx;
}
}
}
</style>