vue 折叠面板

该文章展示了一个用Vue.js编写的多级折叠面板组件,用于显示具有树形结构的数据。组件包含递归渲染子节点的能力,支持点击展开和关闭,以及过渡动画效果。
摘要由CSDN通过智能技术生成

<template>

<div class="accordion-root">

<ul class="list-root">

<multilevel-accordion-children

v-for="(child, index) in tree.children"

:key="index"

:tree="child"

:position="index"

:interleaveOffset="1"

:reference="`${index}`"

:level="0"

:marginLeft="marginLeft"

>

<template slot-scope="_">

<slot

:tree="_.tree"

:interleaved="_.interleaved"

:expanded="_.expanded"

:level="_.level"

:leaf="_.leaf"

></slot>

</template>

</multilevel-accordion-children>

</ul>

</div>

</template>

<script>

import MultilevelAccordionChildren from "./MultilevelAccordionChildren.vue";

export default {

props: {

tree: {

type: Object

},

marginLeft: {

type: Number,

default: 0

}

},

components: {

MultilevelAccordionChildren

}

};

</script>

子组件~~~~~~~~~~~~~~~~~~~

<template>

<div class="accordion-children">

<li>

<div class="accordion" @click="togglePanel()">

<slot

:tree="tree"

:interleaved="interleaved"

:expanded="expanded"

:level="level"

:leaf="leaf"

></slot>

</div>

<div

v-if="!leaf"

class="panel expandible panel-transition"

:ref="`panel-${reference}`"

:style="panelStyle"

>

<ul :style="`margin-left: ${marginLeft}rem;`">

<multilevel-accordion-children

v-for="(child, index) in tree.children"

:key="index"

:tree="child"

:reference="`${reference}-${index}`"

:ref="`childs-${reference}`"

:position="index"

:interleaveOffset="interleaveOffset + position + 1"

:level="level + 1"

:marginLeft="marginLeft"

@updateHeight="updateHeight"

>

<template slot-scope="_">

<slot

:tree="_.tree"

:interleaved="_.interleaved"

:expanded="_.expanded"

:level="_.level"

:leaf="_.leaf"

></slot>

</template>

</multilevel-accordion-children>

</ul>

</div>

</li>

</div>

</template>

<script>

import MultilevelAccordionChildren from "./MultilevelAccordionChildren.vue";

export default {

name: "multilevel-accordion-children",

props: {

tree: {

type: Object,

},

reference: {

type: String,

required: true,

},

interleaveOffset: {

type: Number,

required: true,

},

position: {

type: Number,

required: true,

},

level: {

type: Number,

required: true,

},

marginLeft: {

type: Number,

default: 0,

},

},

components: {

MultilevelAccordionChildren,

},

data() {

return {

isShow: false,

panelStyle: "",

interleaved: ((this.interleaveOffset % 2) + this.position) % 2 == 0,

expanded: false,

};

},

methods: {

togglePanel() {

if (!this.expanded) {

this.expand();

} else {

this.shrink();

}

},

expand() {

if (this.leaf) return null;

if (!this.expanded) {

let el = this.$refs[`panel-${this.reference}`];

this.panelStyle = `max-height: ${el.scrollHeight}px;overflow: initial;`;

this.expanded = true;

this.$emit("updateHeight", el.scrollHeight);

}

},

shrink() {

if (this.leaf) return null;

this.panelStyle = "max-height: 0px;overflow: hidden;";

this.expanded = false;

},

updateHeight(childrenHeight) {

if (this.expanded) {

let el = this.$refs[`panel-${this.reference}`];

this.panelStyle = `max-height: ${el.scrollHeight + childrenHeight}px;`;

this.$emit("updateHeight", el.scrollHeight + childrenHeight);

}

},

},

computed: {

leaf() {

if (this.tree.leaf != undefined) return this.tree.leaf;

if (this.tree.children == undefined) return true;

return this.tree.children.length == 0;

},

},

};

</script>

<style scoped>

.accordion {

text-align: left;

display: flex;

}

.panel {

max-height: 0;

/* overflow: hidden; */

}

.panel-transition {

transition: max-height 0.2s ease-out;

}

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值