前言:本文是基于uniapp+Vue3编写的小程序版本,如果想找Web版本的话,请参考这两篇文章拜托,css这样实现多行文本“展开收起” 超酷的好吧、CSS 实现多行文本“展开收起”
1. 效果
首先展示一下做出来的效果
虽然看起来还是有点僵硬,但是好歹算是有点那意思了T.T(毕业设计,怎么简单怎么来0.0)
2. 实现
2.1 展开按钮定位
这里我是按照CSS 实现多行文本“展开收起”这篇文章的步骤来的,简单来说就是利用伪元素+浮动+BFC来实现按钮定位,使用flex布局实现高度不确定情况下按钮仍处于右下角。
具体实现可以看文章,大佬写的非常详细,我就不献丑了~~
2.2 动态截断
这个文本组件还有一个要求是当行数少于x行时,默认展开;当行数大于x行时,将行数缩减为x行,并展示展开按钮
小于x行时
大于x行时
如果要做到动态截取高度的话,就需要能在组件挂载的时候获取到组件的高度,然后判断是否到达了截取阈值,进行选择性截取
但是不要忘记我们的平台是坑爹的小程序,小程序本身是没有DOM节点的,也就是说不能像Web一样直接用querySelector来获取DOM节点。那难道我们就要放弃这个功能了吗??
其实微信官方也知道这个问题,因此提供了一个专门的API用来查询子节点wx.createSelectorQuery(),在uniapp中是uni.createSelectorQuery()(我在使用的时候发现似乎只对子组件起作用,对于用view和其他标签组成的盒子似乎没有效果,不知道是不是我的姿势不对)
既然找到了工具,那么接下来就是开始使用啦。但是这里有一个问题,由于子组件需要在挂载之后才能被作为节点获取,因此获取节点的方法应该要放到onReady或者onLoad中使用
onReady(() => {
show();
});
function show() {
let query = uni.createSelectorQuery();
query
.select("#content")
.fields(
{
size: true,
},
data => {
// 获取到元素的高度,log出来
console.log(data.height);
},
)
.exec();
}
为了获取整个组件的高度,赋值应该被放到获取高度之后
function show() {
let query = uni.createSelectorQuery();
query
.select("#content")
.fields(
{
size: true,
},
data => {
console.log(data.height);
if (/*判断条件*/) {
showTotalInfo.value = true;
} else {
showTotalInfo.value = false;
}
},
)
.exec();
}
但是这样就引出了一个问题,到底应该怎么判断有没有到截断阈值?
2.3 阈值问题
又是坑爹的小程序,小程序本身并没有window对象,因此也没办法像拜托,css这样实现多行文本“展开收起” 超酷的好吧这篇文章一样使用这种方法
对此,我的解决方法是设置固定的line-height值,然后根据这个值的比例设置静态的截断阈值(建议直接使用px设置line-height,因为uni.createSelectorQuery()方法获取的高度是px单位,而小程序的rpx和px是存在2.x倍的换算关系的,所以建议直接使用px,省心省力)
2.4 动态传值
那么就只剩下最后一个问题了,如何在组件已经挂载的情况下,更新子组件的值。其实很简单,只需要使用Vue的watch来监听props就可以了
watch(
props,
(newValue, oldValue) => {
// todo
}
}
);
3. 结语
如开头所说,这只是我用于我毕设设计的一个简单组件,还有很多待完善的地方,这里分享出来只是为了提供一种思路,因为我在找资料的时候很少看到有uniapp+vue3的案例,就作为记录分享一下我对于uniapp和小程序的一点见解,如果有写的不对或者任何建议,恳请指出,感激不尽!