Vue3+uniapp 多行文字缩进组件

1,547 阅读3分钟

前言:本文是基于uniapp+Vue3编写的小程序版本,如果想找Web版本的话,请参考这两篇文章拜托,css这样实现多行文本“展开收起” 超酷的好吧CSS 实现多行文本“展开收起”

1. 效果

首先展示一下做出来的效果

展示效果.gif

虽然看起来还是有点僵硬,但是好歹算是有点那意思了T.T(毕业设计,怎么简单怎么来0.0)

2. 实现

2.1 展开按钮定位

这里我是按照CSS 实现多行文本“展开收起”这篇文章的步骤来的,简单来说就是利用伪元素+浮动+BFC来实现按钮定位,使用flex布局实现高度不确定情况下按钮仍处于右下角。

具体实现可以看文章,大佬写的非常详细,我就不献丑了~~

2.2 动态截断

这个文本组件还有一个要求是当行数少于x行时,默认展开;当行数大于x行时,将行数缩减为x行,并展示展开按钮

小于x行时

图片.png

大于x行时

图片.png

如果要做到动态截取高度的话,就需要能在组件挂载的时候获取到组件的高度,然后判断是否到达了截取阈值,进行选择性截取

但是不要忘记我们的平台是坑爹的小程序,小程序本身是没有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这样实现多行文本“展开收起” 超酷的好吧这篇文章一样使用这种方法

图片.png

对此,我的解决方法是设置固定的line-height值,然后根据这个值的比例设置静态的截断阈值(建议直接使用px设置line-height,因为uni.createSelectorQuery()方法获取的高度是px单位,而小程序的rpxpx是存在2.x倍的换算关系的,所以建议直接使用px,省心省力)

图片.png

2.4 动态传值

那么就只剩下最后一个问题了,如何在组件已经挂载的情况下,更新子组件的值。其实很简单,只需要使用Vuewatch来监听props就可以了

watch(
      props,
      (newValue, oldValue) => {
        // todo
        }
      }
    );

3. 结语

如开头所说,这只是我用于我毕设设计的一个简单组件,还有很多待完善的地方,这里分享出来只是为了提供一种思路,因为我在找资料的时候很少看到有uniapp+vue3的案例,就作为记录分享一下我对于uniapp和小程序的一点见解,如果有写的不对或者任何建议,恳请指出,感激不尽!