123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <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"
- >
-
-
- <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>
-
- </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';
-
- const animation = uni.requireNativePlugin('animation')
- const dom = uni.requireNativePlugin('dom')
-
-
- export default {
- name: "u-collapse-item",
- mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
- data() {
- return {
- elId: uni.$u.guid(),
-
- animationData: {},
-
- expanded: false,
-
- showBorder: false,
-
- animating: false,
-
- parentData: {
- accordion: false,
- border: false
- }
- };
- },
- watch: {
- expanded(n) {
- clearTimeout(this.timer)
- this.timer = null
-
- 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() {
-
- this.getParentData('u-collapse')
- },
- async setContentAnimate() {
-
-
- const rect = await this.queryRect()
- const height = this.expanded ? rect.height : 0
- this.animating = true
-
- const ref = this.$refs['animation'].ref
- animation.transition(ref, {
- styles: {
- height: height + 'px'
- },
- duration: this.duration,
-
- needLayout: true,
- timingFunction: 'ease-in-out',
- }, () => {
- this.animating = false
- })
-
-
- const animation = uni.createAnimation({
- timingFunction: 'ease-in-out',
- });
- animation
- .height(height)
- .step({
- duration: this.duration,
- })
- .step()
-
- this.animationData = animation.export()
-
- uni.$u.sleep(this.duration).then(() => {
- this.animating = false
- })
-
- },
-
- clickHandler() {
- if (this.disabled && this.animating) return
-
- this.parent && this.parent.onChange(this)
- },
-
- queryRect() {
-
-
-
- return new Promise(resolve => {
- this.$uGetRect(`#${this.elId}`).then(size => {
- resolve(size)
- })
- })
-
-
-
-
- return new Promise(resolve => {
- dom.getComponentRect(this.$refs[this.elId], res => {
- resolve(res.size)
- })
- })
-
- }
- },
- };
- </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>
|