You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

u-collapse-item.vue 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <view class="u-collapse-item" :style="[itemStyle]">
  3. <view :hover-stay-time="200" class="u-collapse-head" @tap.stop="headClick" :hover-class="hoverClass" :style="[headStyle]">
  4. <block v-if="!$slots['title-all']">
  5. <view v-if="!$slots['title']" class="u-collapse-title u-line-1" :style="[{ textAlign: align ? align : 'left' },
  6. isShow && activeStyle && !arrow ? activeStyle : '']">
  7. {{ title }}
  8. </view>
  9. <slot v-else name="title" />
  10. <view class="u-icon-wrap">
  11. <u-icon v-if="arrow" :color="arrowColor" :class="{ 'u-arrow-down-icon-active': isShow }"
  12. class="u-arrow-down-icon" name="arrow-down"></u-icon>
  13. </view>
  14. </block>
  15. <slot v-else name="title-all" />
  16. </view>
  17. <view class="u-collapse-body" :style="[{
  18. height: isShow ? height + 'px' : '0'
  19. }]">
  20. <view class="u-collapse-content" :id="elId" :style="[bodyStyle]">
  21. <slot></slot>
  22. </view>
  23. </view>
  24. </view>
  25. </template>
  26. <script>
  27. /**
  28. * collapseItem 手风琴Item
  29. * @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
  30. * @tutorial https://www.uviewui.com/components/collapse.html
  31. * @property {String} title 面板标题
  32. * @property {String Number} index 主要用于事件的回调,标识那个Item被点击
  33. * @property {Boolean} disabled 面板是否可以打开或收起(默认false)
  34. * @property {Boolean} open 设置某个面板的初始状态是否打开(默认false)
  35. * @property {String Number} name 唯一标识符,如不设置,默认用当前collapse-item的索引值
  36. * @property {String} align 标题的对齐方式(默认left)
  37. * @property {Object} active-style 不显示箭头时,可以添加当前选择的collapse-item活动样式,对象形式
  38. * @event {Function} change 某个item被打开或者收起时触发
  39. * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
  40. */
  41. export default {
  42. name: "u-collapse-item",
  43. emits: ["change"],
  44. props: {
  45. // 标题
  46. title: {
  47. type: String,
  48. default: ''
  49. },
  50. // 标题的对齐方式
  51. align: {
  52. type: String,
  53. default: 'left'
  54. },
  55. // 是否可以点击收起
  56. disabled: {
  57. type: Boolean,
  58. default: false
  59. },
  60. // collapse显示与否
  61. open: {
  62. type: Boolean,
  63. default: false
  64. },
  65. // 唯一标识符
  66. name: {
  67. type: [Number, String],
  68. default: ''
  69. },
  70. //活动样式
  71. activeStyle: {
  72. type: Object,
  73. default () {
  74. return {}
  75. }
  76. },
  77. // 标识当前为第几个
  78. index: {
  79. type: [String, Number],
  80. default: ''
  81. }
  82. },
  83. data() {
  84. return {
  85. isShow: false,
  86. elId: this.$u.guid(),
  87. height: 0, // body内容的高度
  88. headStyle: {}, // 头部样式,对象形式
  89. bodyStyle: {}, // 主体部分样式
  90. itemStyle: {}, // 每个item的整体样式
  91. arrowColor: '', // 箭头的颜色
  92. hoverClass: '', // 头部按下时的效果样式类
  93. arrow: true, // 是否显示右侧箭头
  94. };
  95. },
  96. watch: {
  97. open(val) {
  98. this.isShow = val;
  99. }
  100. },
  101. created() {
  102. this.parent = false;
  103. // 获取u-collapse的信息,放在u-collapse是为了方便,不用每个u-collapse-item写一遍
  104. this.isShow = this.open;
  105. },
  106. methods: {
  107. // 异步获取内容,或者动态修改了内容时,需要重新初始化
  108. init() {
  109. this.parent = this.$u.$parent.call(this, 'u-collapse');
  110. if(this.parent) {
  111. this.nameSync = this.name ? this.name : this.parent.childrens.length;
  112. // 不存在时才添加本实例
  113. !this.parent.childrens.includes(this) && this.parent.childrens.push(this);
  114. this.headStyle = this.parent.headStyle;
  115. this.bodyStyle = this.parent.bodyStyle;
  116. this.arrowColor = this.parent.arrowColor;
  117. this.hoverClass = this.parent.hoverClass;
  118. this.arrow = this.parent.arrow;
  119. this.itemStyle = this.parent.itemStyle;
  120. }
  121. this.$nextTick(() => {
  122. this.queryRect();
  123. });
  124. },
  125. // 点击collapsehead头部
  126. headClick() {
  127. if (this.disabled) return;
  128. if (this.parent && this.parent.accordion == true) {
  129. this.parent.childrens.map(val => {
  130. // 自身不设置为false,因为后面有this.isShow = !this.isShow;处理了
  131. if (this != val) {
  132. val.isShow = false;
  133. }
  134. });
  135. }
  136. this.isShow = !this.isShow;
  137. // 触发本组件的事件
  138. this.$emit('change', {
  139. index: this.index,
  140. show: this.isShow
  141. })
  142. // 只有在打开时才发出事件
  143. if (this.isShow) this.parent && this.parent.onChange();
  144. this.$forceUpdate();
  145. },
  146. // 查询内容高度
  147. queryRect() {
  148. // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
  149. // 组件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不同
  150. this.$uGetRect('#' + this.elId).then(res => {
  151. this.height = res.height;
  152. })
  153. }
  154. },
  155. mounted() {
  156. this.init();
  157. }
  158. };
  159. </script>
  160. <style lang="scss" scoped>
  161. @import "../../libs/css/style.components.scss";
  162. .u-collapse-head {
  163. position: relative;
  164. @include vue-flex;
  165. justify-content: space-between;
  166. align-items: center;
  167. color: $u-main-color;
  168. font-size: 30rpx;
  169. line-height: 1;
  170. padding: 24rpx 0;
  171. text-align: left;
  172. }
  173. .u-collapse-title {
  174. flex: 1;
  175. overflow: hidden;
  176. }
  177. .u-arrow-down-icon {
  178. transition: all 0.3s;
  179. margin-right: 20rpx;
  180. margin-left: 14rpx;
  181. }
  182. .u-arrow-down-icon-active {
  183. transform: rotate(180deg);
  184. transform-origin: center center;
  185. }
  186. .u-collapse-body {
  187. overflow: hidden;
  188. transition: all 0.3s;
  189. }
  190. .u-collapse-content {
  191. overflow: hidden;
  192. font-size: 28rpx;
  193. color: $u-tips-color;
  194. text-align: left;
  195. }
  196. </style>