| ¶Ô±ÈÐÂÎļþ | 
|  |  |  | 
|---|
|  |  |  | <template> | 
|---|
|  |  |  | <view class="u-collapse-item"> | 
|---|
|  |  |  | <u-cell | 
|---|
|  |  |  | :title="title" | 
|---|
|  |  |  | :value="value" | 
|---|
|  |  |  | :label="label" | 
|---|
|  |  |  | :icon="icon" | 
|---|
|  |  |  | :isLink="isLink" | 
|---|
|  |  |  | :clickable="clickable" | 
|---|
|  |  |  | :border="parentData.border && showBorder" | 
|---|
|  |  |  | @click="clickHandler" | 
|---|
|  |  |  | :arrowDirection="expanded ? 'up' : 'down'" | 
|---|
|  |  |  | :disabled="disabled" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <!-- #ifndef MP-WEIXIN --> | 
|---|
|  |  |  | <!-- å¾®ä¿¡å°ç¨åºä¸æ¯æï¼å ä¸ºå¾®ä¿¡ä¸ä¸æ¯æ <slot name="title" slot="title" />çåæ³ --> | 
|---|
|  |  |  | <template slot="title"> | 
|---|
|  |  |  | <slot name="title"></slot> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <template slot="icon"> | 
|---|
|  |  |  | <slot name="icon"></slot> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <template slot="value"> | 
|---|
|  |  |  | <slot name="value"></slot> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <template slot="right-icon"> | 
|---|
|  |  |  | <slot name="right-icon"></slot> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  | <!-- #endif --> | 
|---|
|  |  |  | </u-cell> | 
|---|
|  |  |  | <view | 
|---|
|  |  |  | class="u-collapse-item__content" | 
|---|
|  |  |  | :animation="animationData" | 
|---|
|  |  |  | ref="animation" | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <view | 
|---|
|  |  |  | class="u-collapse-item__content__text content-class" | 
|---|
|  |  |  | :id="elId" | 
|---|
|  |  |  | :ref="elId" | 
|---|
|  |  |  | ><slot /></view> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | <u-line v-if="parentData.border"></u-line> | 
|---|
|  |  |  | </view> | 
|---|
|  |  |  | </template> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <script> | 
|---|
|  |  |  | import props from './props.js'; | 
|---|
|  |  |  | // #ifdef APP-NVUE | 
|---|
|  |  |  | const animation = uni.requireNativePlugin('animation') | 
|---|
|  |  |  | const dom = uni.requireNativePlugin('dom') | 
|---|
|  |  |  | // #endif | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * collapseItem æå é¢æ¿Item | 
|---|
|  |  |  | * @description éè¿æå é¢æ¿æ¶çº³å
容åºåï¼æé
u-collapse使ç¨ï¼ | 
|---|
|  |  |  | * @tutorial https://www.uviewui.com/components/collapse.html | 
|---|
|  |  |  | * @property {String}         title       æ é¢ | 
|---|
|  |  |  | * @property {String}         value       æ é¢å³ä¾§å
容 | 
|---|
|  |  |  | * @property {String}         label       æ é¢ä¸æ¹çæè¿°ä¿¡æ¯ | 
|---|
|  |  |  | * @property {Boolean}         disbled    æ¯å¦ç¦ç¨æå é¢æ¿ ( é»è®¤ false ) | 
|---|
|  |  |  | * @property {Boolean}         isLink       æ¯å¦å±ç¤ºå³ä¾§ç®å¤´å¹¶å¼å¯ç¹å»å馠( é»è®¤ true ) | 
|---|
|  |  |  | * @property {Boolean}         clickable   æ¯å¦å¼å¯ç¹å»å馠( é»è®¤ true ) | 
|---|
|  |  |  | * @property {Boolean}         border      æ¯å¦æ¾ç¤ºå
边桠( é»è®¤ true ) | 
|---|
|  |  |  | * @property {String}         align      æ é¢ç坹齿¹å¼ ( é»è®¤ 'left' ) | 
|---|
|  |  |  | * @property {String | Number}   name      å¯ä¸æ è¯ç¬¦ | 
|---|
|  |  |  | * @property {String}         icon      æ é¢å·¦ä¾§å¾çï¼å¯ä¸ºç»å¯¹è·¯å¾çå¾çæå
ç½®å¾æ  | 
|---|
|  |  |  | * @event {Function}         change          æä¸ªitem被æå¼æè
æ¶èµ·æ¶è§¦å | 
|---|
|  |  |  | * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item> | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | export default { | 
|---|
|  |  |  | name: "u-collapse-item", | 
|---|
|  |  |  | mixins: [uni.$u.mpMixin, uni.$u.mixin, props], | 
|---|
|  |  |  | data() { | 
|---|
|  |  |  | return { | 
|---|
|  |  |  | elId: uni.$u.guid(), | 
|---|
|  |  |  | // uni.createAnimationçå¯¼åºæ°æ® | 
|---|
|  |  |  | animationData: {}, | 
|---|
|  |  |  | // æ¯å¦å±å¼ç¶æ | 
|---|
|  |  |  | expanded: false, | 
|---|
|  |  |  | // æ ¹æ®expandedç¡®å®æ¯å¦æ¾ç¤ºborderï¼ä¸ºäºæ§å¶å±å¼æ¶ï¼cellçä¸å线æ´å¥½çæ¾ç¤ºææï¼è¿è¡ä¸å®æ¶é´çå»¶æ¶ | 
|---|
|  |  |  | showBorder: false, | 
|---|
|  |  |  | // æ¯å¦å¨ç»ä¸ï¼å¦ææ¯åä¸å
许继ç»è§¦åç¹å» | 
|---|
|  |  |  | animating: false, | 
|---|
|  |  |  | // ç¶ç»ä»¶u-collapseçåæ° | 
|---|
|  |  |  | parentData: { | 
|---|
|  |  |  | accordion: false, | 
|---|
|  |  |  | border: false | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | watch: { | 
|---|
|  |  |  | expanded(n) { | 
|---|
|  |  |  | clearTimeout(this.timer) | 
|---|
|  |  |  | this.timer = null | 
|---|
|  |  |  | // è¿éæ ¹æ®expandedç弿¥è¿è¡ä¸å®çå»¶æ¶ï¼æ¯ä¸ºäºcellçä¸å线æ´å¥½çæ¾ç¤ºææ | 
|---|
|  |  |  | this.timer = setTimeout(() => { | 
|---|
|  |  |  | this.showBorder = n | 
|---|
|  |  |  | }, n ? 10 : 290) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | mounted() { | 
|---|
|  |  |  | this.init() | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | methods: { | 
|---|
|  |  |  | // å¼æ¥è·åå
å®¹ï¼æè
å¨æä¿®æ¹äºå
容æ¶ï¼éè¦éæ°åå§å | 
|---|
|  |  |  | init() { | 
|---|
|  |  |  | // åå§åæ°æ® | 
|---|
|  |  |  | this.updateParentData() | 
|---|
|  |  |  | if (!this.parent) { | 
|---|
|  |  |  | return uni.$u.error('u-collapse-itemå¿
é¡»è¦æé
u-collapseç»ä»¶ä½¿ç¨') | 
|---|
|  |  |  | } | 
|---|
|  |  |  | const { | 
|---|
|  |  |  | value, | 
|---|
|  |  |  | accordion, | 
|---|
|  |  |  | children = [] | 
|---|
|  |  |  | } = this.parent | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (accordion) { | 
|---|
|  |  |  | if (uni.$u.test.array(value)) { | 
|---|
|  |  |  | return uni.$u.error('æé£ç´æ¨¡å¼ä¸ï¼u-collapseç»ä»¶çvalueåæ°ä¸è½ä¸ºæ°ç»') | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.expanded = this.name == value | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | if (!uni.$u.test.array(value) && value !== null) { | 
|---|
|  |  |  | return uni.$u.error('éæé£ç´æ¨¡å¼ä¸ï¼u-collapseç»ä»¶çvalueåæ°å¿
须为æ°ç»') | 
|---|
|  |  |  | } | 
|---|
|  |  |  | this.expanded = (value || []).some(item => item == this.name) | 
|---|
|  |  |  | } | 
|---|
|  |  |  | // è®¾ç½®ç»ä»¶çå±å¼ææ¶èµ·ç¶æ | 
|---|
|  |  |  | this.$nextTick(function() { | 
|---|
|  |  |  | this.setContentAnimate() | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | updateParentData() { | 
|---|
|  |  |  | // æ¤æ¹æ³å¨mixinä¸ | 
|---|
|  |  |  | this.getParentData('u-collapse') | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | async setContentAnimate() { | 
|---|
|  |  |  | // æ¯æ¬¡é¢æ¿æå¼æè
æ¶èµ·æ¶ï¼é½æ¥è¯¢å
素尺寸 | 
|---|
|  |  |  | // å¥½å¤æ¯ï¼ç¶ç»ä»¶ä»æå¡ç«¯è·åå
容åï¼åæ´æå é¢æ¿åå¯ä»¥è·å¾ææ°çé«åº¦ | 
|---|
|  |  |  | const rect = await this.queryRect() | 
|---|
|  |  |  | const height = this.expanded ? rect.height : 0 | 
|---|
|  |  |  | this.animating = true | 
|---|
|  |  |  | // #ifdef APP-NVUE | 
|---|
|  |  |  | const ref = this.$refs['animation'].ref | 
|---|
|  |  |  | animation.transition(ref, { | 
|---|
|  |  |  | styles: { | 
|---|
|  |  |  | height: height + 'px' | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | duration: this.duration, | 
|---|
|  |  |  | // å¿
须设置为trueï¼å¦åä¼å°é¢æ¿æ¶èµ·æå±å¼æ¶ï¼é¡µé¢å
¶ä»å
ç´ ä¸ä¼éä¹è°æ´å®ä»¬çå¸å± | 
|---|
|  |  |  | needLayout: true, | 
|---|
|  |  |  | timingFunction: 'ease-in-out', | 
|---|
|  |  |  | }, () => { | 
|---|
|  |  |  | this.animating = false | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | // #endif | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // #ifndef APP-NVUE | 
|---|
|  |  |  | const animation = uni.createAnimation({ | 
|---|
|  |  |  | timingFunction: 'ease-in-out', | 
|---|
|  |  |  | }); | 
|---|
|  |  |  | animation | 
|---|
|  |  |  | .height(height) | 
|---|
|  |  |  | .step({ | 
|---|
|  |  |  | duration: this.duration, | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | .step() | 
|---|
|  |  |  | // å¯¼åºå¨ç»æ°æ®ç»é¢æ¿çanimationDataå¼ | 
|---|
|  |  |  | this.animationData = animation.export() | 
|---|
|  |  |  | // æ è¯å¨ç»ç»æ | 
|---|
|  |  |  | uni.$u.sleep(this.duration).then(() => { | 
|---|
|  |  |  | this.animating = false | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | // #endif | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | // ç¹å»collapseheadå¤´é¨ | 
|---|
|  |  |  | clickHandler() { | 
|---|
|  |  |  | if (this.disabled && this.animating) return | 
|---|
|  |  |  | // è®¾ç½®æ¬ç»ä»¶ä¸ºç¸åçç¶æ | 
|---|
|  |  |  | this.parent && this.parent.onChange(this) | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | // æ¥è¯¢å
容é«åº¦ | 
|---|
|  |  |  | queryRect() { | 
|---|
|  |  |  | // #ifndef APP-NVUE | 
|---|
|  |  |  | // $uGetRect为uViewèªå¸¦çèç¹æ¥è¯¢ç®åæ¹æ³ï¼è¯¦è§ææ¡£ä»ç»ï¼https://www.uviewui.com/js/getRect.html | 
|---|
|  |  |  | // ç»ä»¶å
é¨ä¸è¬ç¨this.$uGetRectï¼å¯¹å¤ç为uni.$u.getRectï¼äºè
åè½ä¸è´ï¼åç§°ä¸å | 
|---|
|  |  |  | return new Promise(resolve => { | 
|---|
|  |  |  | this.$uGetRect(`#${this.elId}`).then(size => { | 
|---|
|  |  |  | resolve(size) | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | // #endif | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // #ifdef APP-NVUE | 
|---|
|  |  |  | // nvueä¸ï¼ä½¿ç¨domæ¨¡åæ¥è¯¢å
ç´ é«åº¦ | 
|---|
|  |  |  | // è¿åä¸ä¸ªpromiseï¼è®©è°ç¨æ¤æ¹æ³ç主ä½è½ä½¿ç¨thenåè° | 
|---|
|  |  |  | return new Promise(resolve => { | 
|---|
|  |  |  | dom.getComponentRect(this.$refs[this.elId], res => { | 
|---|
|  |  |  | resolve(res.size) | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | // #endif | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }; | 
|---|
|  |  |  | </script> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | <style lang="scss" scoped> | 
|---|
|  |  |  | @import "../../libs/css/components.scss"; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | .u-collapse-item { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | &__content { | 
|---|
|  |  |  | overflow: hidden; | 
|---|
|  |  |  | height: 0; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | &__text { | 
|---|
|  |  |  | padding: 12px 15px; | 
|---|
|  |  |  | color: $u-content-color; | 
|---|
|  |  |  | font-size: 14px; | 
|---|
|  |  |  | line-height: 18px; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | </style> | 
|---|