当前位置: 首页 > Web前端 > vue.js

实现省略、展开、收起多行文本的功能——用Electron+Vue写一个播放器(二)

时间:2023-04-01 11:53:54 vue.js

前言今天继续琢磨播放器的用户体验细节,发现歌单、歌手,专辑,主流播放器mv详情页描述文字过长会自动折叠,提供展开按钮,点击展开即可。真的很方便。看自己的滚动体会,滚动太快看不清,滚动慢浪费。时间,简直了。下面来实现展开和折叠长文本的功能。设计这个功能并不难。首先,您需要一个元素来存储描述文本。此元素的高度是文本本身的高度。很多用户喜欢用换行和空行来格式化漂亮的文字,为了保留文字本身换行和空行的内容,这里我使用

元素作为容器(你也可以设置white-space属性保留连续空格),然后需要一个固定高度的父容器,并设置overflow隐藏,然后放置一个展开/折叠按钮,点击展开时取消父容器的固定高度,并恢复点击折叠时父容器的固定高度,至此主要工作完成,很简单,最后可以美化一下按钮。下面来看看实现后的实际效果。单击此处查看演示的简单版本。由于这个展开和折叠功能需要在很多页面中使用,所以考虑将其抽离成一个通用的组件。首先需要声明需要接收的propsprops:{description:{type:String,default:''},//描述文字lineNumbers:{type:Number,default:3},//最大显示行折叠状态下的数字lineHeight:{type:Number,default:22},//行高fontSize:{type:Number,default:14},//字体大小btnOutOfWords:{type:Boolean,default:true}//是否展开按钮不覆盖文字},这些是一些简单的配置,接下来需要使用一些内部数据来控制组件的运行,data(){return{descHasOverflow:false,//内容是否溢出showMore:false,//是否展开saveDescription:''//转义后的描述内容}}我们需要在组件初始化的时候判断新的内容是否溢出父容器,每次监听描述内容的变化,并将结果记录在descHasOverflow中。只需比较元素的clientHeight和scrollHeight,将判断逻辑封装在init方法init(){this.descOverflow=false//恢复非溢出状态this.showMore=false//恢复折叠状态this.saveDescription=this.saveDescription&&this.description.replace(/[<]/g,'&lt;')//转义<符号//如果不使用this.$nextTick会发生什么?this.$nextTick(()=>{constdesc=this.$refs.descif(desc.clientHeight内部,则其及其子组件自始至终只会触发一次mountedhook,所以在mounted内部调用init是不够的钩定义一个响应按钮事件的方法handleShowMore(){this.showMore=!this.showMore}在模板中,根据shouMore的不同,对父容器元素和展开/折叠按钮应用不同的样式。最后加上1亿点的css代码美化一下就大功告成了。单击此处查看完整代码。最后,在上面提到的init方法中,我们监听了description的变化,从而在$nextTick方法中执行了操作dom的代码。如果不使用该方法,则立即同步计算元素的clientHeight和scrollHeight。此时参与计算的dom元素是description变化前的结果(如果只是在mountedhook中,不会出现这种情况),因为vue中的虚拟dom是异步渲染的,它会合并所有更新到虚拟同步代码执行完之后的dom,比如example(){for(leti=0;i<100;i++){this.a=i}}调用example方法时,虽然thia.a的值为更改一百次,只会触发一次虚拟dom更新。我们的目的是计算dom更新完成后的高度,而Vue提供的$nextTick方法就是为了这个:为了等待Vue在数据变化后更新完DOM,可以使用Vue.nextTick(回调)在数据改变后立即。这样回调函数就会在DOM更新完成后被调用。它内部使用MutationObserver来监控dom元素的修改。一旦dom元素被修改,就会调用传入的回调函数,确保执行回调函数时dom已经更新。