博主介绍
📢点击下列内容可跳转对应的界面,查看更多精彩内容!
🍎主页:水香木鱼
🍍专栏:后台管理系统
文章目录
简介:这是一篇有关【Vue实现任意内容展开 / 收起功能组件】的文章,博主用
最精简的语言
去表达给前端读者们。
1、collapse组件
<!--展开/收起 组件-->
<template>
<section
class="collapse"
ref="collapse"
:style="{
height: containerH + 'px',
'padding-right': (hideControll ? 0 : 50) + 'px',
}"
>
<div class="collapse-content" ref="content">
<slot></slot>
</div>
<span
v-if="!hideControll"
v-show="controllVisible"
class="collapse-controll"
@click="handleControll"
>
<i
v-show="!hideControllIcon"
class="collapse-controll-icon"
:class="isShow ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"
></i>
{{ isShow ? foldText : unfoldText }}
</span>
</section>
</template>
<script>
export default {
name: "collapse",
model: {
prop: "visible",
event: "change",
},
props: {
visible: Boolean,
// 默认显示的内容高度
defaultHeight: {
type: Number,
default: 100,
},
// 是否隐藏内置控制按钮
hideControll: Boolean,
// 是否隐藏内置控制按钮icon
hideControllIcon: Boolean,
foldText: {
type: String,
default: "收起",
},
unfoldText: {
type: String,
default: "展开",
},
},
data() {
return {
isShow: false,
controllVisible: true,
containerH: this.defaultHeight,
contentH: 0,
DOMWatcher: null,
};
},
watch: {
visible(v) {
if (v) {
this.unfold();
} else {
this.handleFold();
}
},
isShow(v) {
this.$emit("change", v);
},
},
mounted() {
this.init();
this.watch();
if (this.visible) {
this.unfold();
}
},
destroyed() {
this.DOMWatcher.disconnect();
},
methods: {
init() {
this.contentH = this.$refs.content.offsetHeight;
/**
* 当内容变化的同时也是展开状态的话,那么需要更新容器高度
* 1. 当最新的内容高度大于默认高度时,则把容器高度更新最新内容高度一致即可
* 2. 反之,把容器高度设到最小(即默认高度),同时设为收起状态
*/
if (this.isShow) {
if (this.contentH > this.defaultHeight) {
this.containerH = this.contentH;
} else {
this.containerH = this.defaultHeight;
this.isShow = false;
}
}
this.controllVisible = this.contentH > this.defaultHeight; // 控制按钮的显示隐藏
},
watch() {
this.DOMWatcher = new MutationObserver(() => {
// 监测到DOM变化,重新计算高度
this.refresh();
});
this.DOMWatcher.observe(this.$refs.content, {
childList: true,
attributes: true,
characterData: true,
subtree: true,
});
},
refresh() {
this.$nextTick(() => {
this.init();
});
},
handleControll() {
let handle = this.isShow ? this.handleFold : this.unfold;
handle();
},
// 收起
handleFold() {
this.containerH = this.defaultHeight;
this.$nextTick(() => {
this.isShow = false;
});
},
// 展开
unfold() {
const contentH = this.$refs.content.offsetHeight;
if (contentH > this.defaultHeight) {
this.containerH = contentH;
}
this.$nextTick(() => {
this.isShow = true;
});
},
},
};
</script>
<style scoped>
.collapse {
width: 100%;
position: relative;
overflow: hidden;
transition: height 0.28s ease-in-out;
}
.collapse-controll {
position: absolute;
bottom: 0px;
right: 8px;
font-size: 14px;
font-weight: 400;
color: #6abcff;
cursor: pointer;
}
.collapse-controll-icon {
margin-right: 2px;
}
</style>
2、页面使用
<template>
<div>
<!-- 自动适应外层容器宽度 -->
<div style="width: 130px">
<collapse :default-height="34">
<div>详细内容:</div>
<div>水香木鱼欢迎您~</div>
<div>自己定义内容~</div>
<div>页面简洁 美观~~</div>
</collapse>
</div>
</div>
</template>
<script>
import collapse from "@/components/collapse.vue";
export default {
components: { collapse },
};
</script>
相关推荐
⭐Vue实现点击按钮或者图标可编辑输入框
⭐vue实现隐藏浏览器右侧滚动条功能
⭐vue实现keep-alive页面缓存【三步骤配置,一步到位】
⭐vue实现pdf在线预览业务
⭐前端vue正则表达式-隐私脱敏处理