【Vue】使用Vue实现div收缩效果

vue 展开收起(高度不固定,还要有平滑的过渡效果) 找了好多案例都不是很顺滑,最终还是功夫不负有心人,找到了一个非常棒的案例,只是简单地尝试一下,以后使用可以在进行全面的封装来公共使用 <template> <div class="panel"> <!-- body --> <transition name="panel-fade" @enter="enter" @before-leave="beforeLeave" @leave="leave"> <div cla.. 阅读详情

重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

本文原文地址:Microanswer的博客【Vue】使用Vue实现div收缩效果。

一、效果展示

你看到的边框只是为了演示效果需要,实际组件是不会有任何内容的,它只提供收缩功能。此处内容可以是任何内容,组件会自动根据内容高度进行展开,需要用户关心的是否开还是关的状态。开发者也只需关心此状态,故此可以放心的使用本控件,实现页面上部分内容的收缩展示。

图1

二、实现要点

基于css的transition功能实现。通过设置不同的视图高度,再配合一个 transition 过渡动画时长的设定,就可以实现这个功能了。不过很有趣,transition并不支持对height(高度)的变化产生预期的开合效果,但支持对 maxHeight 的变化产生开合效果。因此,咱们设置视图的高度,是通过设置 maxHeight 来实现的。

三、代码实现

1、创建文件

不妨咱们将此组件命名为:ShrinkView 吧。创建新的vue单文件:ShrinkView.vue。此控件需提供一个插槽供使用者放入自己的内容。其初始代码如下:

<template>
    <div>
        <slot></slot>
    </div>
</template>
<style scoped>
</style>

<script>
    export default {
        props: {
        },
        updated () {
        },
        mounted () {
        },
        methods: {
        },
        watch: {
        },
        data () {
            return {
            }
        }
    }
</script>
2、逻辑实现

由于通过 maxHeight 限定视图高度,当内容多于maxHeight 时必然会超出显示,咱们首先添加超出范围进行隐藏的css样式,以及动画开合过渡时间样式:

<template>
    <div class="shrink-view">
        <slot></slot>
    </div>
</template>
<style scoped>
    .shrink-view {
        overflow: hidden;

        -webkit-transition-duration: 300ms;
        -moz-transition-duration: 300ms;
        -ms-transition-duration: 300ms;
        -o-transition-duration: 300ms;
        transition-duration: 300ms;
    }
<style>

<scr....ipt/>

现在,基本样式定义完成,进行下一步设置不同视图高度操作,此步操作可能涉及逻辑思考了。展开,当希望展开时,一定是希望展开到视图内容完整的高度,而此高度的获取,可通过 dom 的 scrollHeight 获取到,在组件挂载到界面、组件内容更新后,都有必要拿到这个高度值进行保存。因此,在 mounted 和 updated 方法里获取该值是最合适不过的地方:

<temp....late/>
<script>
    export default {
        props: {
        },
        updated () {
            this.init();
        },
        mounted () {
            this.init();
        },
        methods: {
            // 因为 updated 和 mounted 里都要使用本方法,所以将本方法提取为一个方法方便调用。使用 nextTick 进一步保证视图高度获取精确。
            init () {
                this.$nextTick(() => {
                    this.contentHeight = this.$el.scrollHeight;
                });
            }
        },
        watch: {
        },
        data () {
            return {
                contentHeight: 0, // 使用此字段保存视图内容的实际高度
            }
        }
    }
<script>

<style scoped>...</style>

代码中使用 contentHeight 字段保存了视图内容的实际高度,现在只需要再设定一个字段来保存开合状态即可,不妨使用 mIsOpen 字段来维护这个状态:

<script>
    export default {
        props: {
            value: Boolean // 定义属性 value,这样v-model的值就可以接收到。
        },
        updated () {
            this.init();
        },
        mounted () {
            this.init();
        },
        methods: {
            // 因为 updated 和 mounted 里都要使用本方法,所以将本方法提取为一个方法方便调用。使用 nextTick 进一步保证视图高度获取精确。
            init () {
                this.$nextTick(() => {
                    this.contentHeight = this.$el.scrollHeight;
                });
            }
        },
        watch: {
            // 监听 value 的变化,并将变化值赋值给 本组件维护的 mIsOpen 字段中
            value (newValue) {
                this.mIsOpen = newValue;
            },

            // 监听 mIsOpen 的变化,一旦变化,将input事件暴露,这样可实现v-model双向绑定。
            mIsOpen (newValue) {
                this.$emit('input', newValue);
            }
        },
        data () {
            return {
                contentHeight: 0, // 使用此字段保存视图内容的实际高度
                mIsOpen:       this.value  // 保存开合状态,默认值使用prop定义的属性(即v-model的值)
            }
        }
    }
<script>

代码中定义了一个data的字段 mIsOpen 和 prop的属性字段 value,前者保存当前组件的开合状态,后者连接了使用者传入的开合状态,并监听属性value,将改变的值赋值给dada的mIsOpen字段,实现组件内的状态变更。同时组件内状态变化后暴露事件input,从而实现双向绑定。

最后,只需要将mIsOpen的不同状态反应到template内,进行视图响应,那么整体任务就算完成:

<template>
    <div class="shrink-view" :style="{maxHeight: (mIsOpen?contentHeight:0) + 'px'}">
        <slot></slot>
    </div>
</template>
<script>...</script>

<style>...</style>

实现也非常简单,只需要根据 mIsOpen 不同的状态,为 maxHeight 赋值不同的高度,即可实现。

现在完整的代码如下:

<!-- ShrinkView.vue -->
<template>
    <div class="shrink-view" :style="{maxHeight: (mIsOpen?contentHeight:0) + 'px'}">
        <slot></slot>
    </div>
</template>

<script>
    export default {
        props: {
            value: Boolean
        },
        updated () {
            this.init();
        },
        mounted () {
            this.init();
        },
        methods: {
            init () {
                this.$nextTick(() => {
                    this.contentHeight = this.$el.scrollHeight;
                });
            }
        },
        watch: {
            value (newValue) {
                this.mIsOpen = newValue;
            },
            mIsOpen (newValue) {
                this.$emit('input', newValue);
            }
        },
        data () {
            return {
                contentHeight: 0,
                mIsOpen: this.value,
            }
        }
    }
</script>

<style scoped>
    .shrink-view {
        -webkit-transition-duration: 300ms;
        -moz-transition-duration: 300ms;
        -ms-transition-duration: 300ms;
        -o-transition-duration: 300ms;
        transition-duration: 300ms;

        overflow: hidden;
    }
</style>

四、使用

现在可以在其他界面上使用这个组件了。下面我在一个最简单的界面使用了这个组件:

<template>
    <div>
        <h1>Vue实现收缩效果</h1>

        <input type="checkbox" v-model="open">

        <div style="border: 1px solid gray">
            <shrink-view v-model="open">

                    你看到的边框只是为了演示效果需要,实际组件是不会有任何内容的,它只提供收缩功能。
                <hr>
                    此处内容可以是任何内容,组件会自动根据内容高度进行展开,需要用户关系的只需暴露是否开还是关的状态。
                    开发者也只需关系此状态,故此可以放心的使用本控件实现页面上部分内容的收缩展示。

            </shrink-view>
        </div>

    </div>
</template>

<script>
    import ShrinkView from '../components/ShrinkView';

    export default {
        components: {
            ShrinkView
        },
        data () {
            return {
                open: false
            }
        }
    }
</script>

五、不是VUE怎么办?

放心,如果你不是使用的vue,但你通过阅读本文,你便会知道其实现原理,通过 transition 对 maxHeight 支持从而实现 高度 或 宽度的变化动效,不要忘了添加 overflow: hidden 样式,以免内容超出达不到效果。

Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩遇到问题 Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩遇到问题 自定义组件包含在 fragment下面, 不是div 不然展开和收缩会出现字体无法隐藏的问题 如下: 解决菜单导航折叠后文字不隐藏 出现这个问题是因为我们在<el-menu>嵌套中出现了意料之外的<div>,而<el-menu>标签本身希望里面嵌套的是<el-menu-item>,<el-submenu>,<el-menu-item-group>其中之一 但是 阅读详情

相关推荐

支持VUE3 的左靠边 可收缩的 导航栏 完整组件

{ path: '/services', label: '服务项目', icon: 'fas fa-concierge-bell' },{ path: '/about', label: '关于我们', icon: 'fas fa-info-circle' },{ path: '/contact', label: '联系我们', icon: 'fas fa-envelope' }{ path: '/', label: '首页', icon: 'fas fa-home' },支持展开/收缩动画(宽度变化)

u013735911的博客 1230

Vue.js学习笔记(二):点击展开、收缩div之折叠面板效果

本例涉及:绑定点击事件、动态切换类、动态改变dom样式 效果图:点击按钮展开,再次点击按钮收缩 代码: 为了方便查看学习,只上传关键代码语句 Vue实例代码: 可视区域的高度需根据自己的需求调整。 此文章仅供学习交流使用,如果有更好的方法欢迎评论交流~ ...

summer_gf的博客 7844

vue自定义指令--实现div和图片的拖拽,放大,缩小

在开发可视化大屏的过程中碰到甲方只能提供一张图片的地图无法提供经纬度,需要在这张图片实现类似百度地图功能的标点。所以就想实现对图片的拖拽移动然后加上放大和缩小功能。这样来模拟百度地图的小部分功能,然后通过在图片上放小div进行标点,来进行坐标定位,如下图代码已经封装成组件,复制可以。

快来一起学习前端知识把!加油,前端人 2641

vue实现点击按钮展开侧边栏,再点击按钮收起

vue实现点击按钮展开侧边栏,再点击按钮收起

猫巷的博客 4548

vue 点击展开显示更多(点击收起部分隐藏)

功能如下: 这里就需要一开始只显示6个数据,点击展开才显示全部 HTML里调用showdetailList: {{item.title}} {{item.name}} 6 v-on:click=changeFoldState> {{brandFold?'展开':'收起'}}</s

Unity游戏开发客户端面经——数据结构(初级)

Unity游戏开发客户端面经 之 数据结构篇

Sea3752的博客 1万+

使用Vue实现div上下收缩动画效果

【代码】使用Vue实现div上下收缩效果。

前端程序猿的博客 1111

数字IC面试核心:从MUX基础到Glitch-Free时钟切换电路深度剖析

本文深入剖析数字IC设计中的MUX基础原理及其在Glitch-Free时钟切换电路中的应用。从二选一MUX的门级实现到时钟切换中的毛刺问题,详细讲解了同步切换机制和工程优化技巧,帮助工程师掌握高速时钟电路设计的核心要点。

weixin_42629815的博客 325

vue伸缩效果_【Vue】使用Vue实现div收缩效果

重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

weixin_42485489的博客 788

注册电气工程师详细教材

注册电气工程师详细教材

qq_40844444的博客 4251

2025.06.25【微生物】|Emu工具安装与使用详解:全长16S扩增子微生物丰度分析

Emu是一款基于贝叶斯方法的微生物多样性分析工具,专为处理高错误率的长读长16S/18S扩增子数据优化。本文详细介绍了Emu的安装与使用方法:1)通过conda创建独立环境并安装Emu;2)提供SILVA等预构建数据库的下载指南,并说明自定义数据库的构建方法;3)演示单样本和多样本分析流程,解读关键输出文件;4)介绍丰度表合并、分类等级汇总等实用功能扩展;5)建议后续分析方向。文章还附有官方GitHub链接和相关文献资源,为微生物群落结构研究提供了一套完整的分析解决方案。

1256

Vue中固定高的div做展开与收缩操作

Vue中固定高的div做展开与收缩操作 HTML <div class="downUp transition-dom" ref="box" @click="funAnimate"></div> CSS .downUp { height: 36px; } .transition-dom { transition: all .2s linear 0s; } javasc...

qq_44631273的博客 1912

网络可视媒体的智能计算-胡事民

本文为胡事民教授在山大做报告的笔记,现场见下图: 可视媒体是承载视觉信息的媒体类型,如图像、视频等,它具有网络化、海量和无序涌现等特征。 可视媒体计算的研究意义 可视媒体作为一种信息承载的介质,是用来表达语义信息的。那么就有一种介质与信息之间相互转化的问题。转化方向正反两种,举个栗子说明一下: 1. 可视媒体→→\rightarrow语义信息:比如看到画面,理解其中发生的事件、各主题之...

gdymind的博客 2451

elment-ui/plus不定高度容器收缩折叠动画组件

【代码】elment-ui/plus不定高度容器收缩折叠动画组件。

pscool的博客 931

LSM6DS3TR-C IMU传感器入门:从MEMS原理到姿态解算实战

惯性测量单元(IMU)是现代智能设备实现运动感知的核心部件,其基础原理基于微机电系统(MEMS)技术。MEMS加速度计通过检测质量块在惯性力作用下的位移来测量线性加速度,而陀螺仪则利用科里奥利力效应感知角速度。这种技术使得微型化、低成本的6自由度运动测量成为可能,为机器人、无人机、可穿戴设备等提供了关键的空间姿态和运动状态信息。在实际工程中,开发者需要掌握I2C/SPI通信协议、传感器数据读取与校准,并通过互补滤波等算法融合加速度计和陀螺仪数据,实现稳定的姿态解算。LSM6DS3TR-C作为一款高性价比的6

weixin_28684655的博客 596

APP爬虫:Airtest的使用和爬取实战详解

Airtest是一个跨平台的自动化测试工具,主要用于移动应用和游戏的UI自动化测试。它支持图像识别、触摸操作、文本输入等功能,能够模拟真实用户的操作行为。此外,Airtest还具备强大的日志记录和报告生成功能,方便开发者进行调试和分析。图像识别:通过截图匹配元素,无需依赖 UI 层次结构。跨平台支持:支持 Android、iOS 和 Windows 应用。简单易用:提供 IDE 和脚本录制功能,降低使用门槛。

数据知道的博客 9619

vue伸缩效果_vuejs实现折叠面板展开收缩动画效果

vuejs通过css3实现元素固定高度到auto高度的动画和auto高度到固定高度的动画。循环列表,html:{{item.content}}【展开】【收缩】在css上加上动画transition.newslist ul li p {font-size: 14px;color: #555;line-height: 25px;height: 50px;overflow: hidden;transit...

weixin_39898150的博客 900

S7-1200PLC与昆仑通态触摸屏以太网通信的具体方法和步骤(图文)

S7-1200PLC与昆仑通态触摸屏以太网通信的具体方法和步骤(图文)

Robot_PLC_HMI_Automation 1万+

vue实现折叠面板展开与收缩效果

vue中展开与缩放动画,网上大多都是通过监测max-height属性来实现,亲测了一下,有卡顿现象,效果并不理想,最后发现可以通过css+js的方式,通过高度height变化来实现动画。 html代码: <div class="collapse-item" v-for="(item,index) in linkList" :key="item.name"> <div class="collapse-tab" @click="onTabChange(item,index)">.

ouruolaxuhui的专栏 5687

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

vue收缩面板_vuejs实现折叠面板展开收缩动画

vuejs通过css3实现元素固定高度到auto高度的动画和auto高度到固定高度的动画。循环列表,html:<template><div class="newslist"><ul><li v-for="(item,index) in newslist" :key="index"><p class="p" ref="liCon">{{it...

weixin_30030437的博客 1054

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

vuejs实现折叠面板展开收缩动画

vuejs通过css3实现元素固定高度到auto高度的动画和auto高度到固定高度的动画。 循环列表,html: &lt;template&gt; &lt;div class="newslist"&gt; &lt;ul&gt; &lt;li v-for="(item,index) in newslist" :key="index"&gt;

yumihe 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

vue实现展开收缩动画

1、实际效果 展开收起效果.gif 2、代码 <!--css--> .box{ height:200px;width: 200px; background-color:black; } .draw-enter-active, .draw-leave-active { transition: all 1s ease; } .draw-enter, .d...

CaseyWei 6288

Vue的几种展开收缩动画

一、 //需要动画的内容 .router-slid-enter-active, .router-slid-leave-active { transition: all .4s; } .router-slid-enter, .router-slid-leave-active { transform: translate3d(0, 3rem, 0); opacity: 0; } 二、 创建ShrinkView.vue组件 在其它页面引入该组件 ...

qq_42190640的博客 2982

vue实现折叠展开收缩动画

/ 刚开始的时候, 就必须先获取到这个元素的高度(transition需要有两个数值才能产生过渡), 它必须刚开始就是可见的(不能display:none)// 这个时候,box1已经收缩了,但是需要展开,那就必须获取到它的高度(此时它的style的height为0)

pscool的博客 7212

vue 之展开收缩组件

展开收缩组件 <template> <div> <div class="exp-col"> <img v-if="shzk" src="../assets/images/expand.png" alt="" @click="tack"> <img v-else src="../assets/images...

Akatsuki233的博客 1682
上一篇: 桌面网页上实现分享功能,分享到QQ空间、新浪微博、人人网
下一篇: 【Vue,Vuex】为你的vue项目添加vuex支持,并实现全局动态主题颜色修改
Microanswer
博客等级 码龄10年 38粉丝 40原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值