react 多行或单行文本溢出省略显示省略号(...)

需求:

  1. 该组件可以显示文本+按钮的形式,也可以显示纯文本的形式。
  2. 文本可以为单行或多行,为单行时超过最大宽度显示省略号,在有按钮的情况下,按钮在文本之后显示。为多行文本时,默认超过两行省略,再有按钮的情况下按钮在文本之后显示。
  3. 在组件中,定义自定义文本内容:如 按钮标签并将此设置为可选参数。定义文本为必传参数。定义行数并设置默认行数为2行,超过两行进行省略。

使用hooks中的useSafeState, useUpdate等
useUpdate: 返回一个函数,调用该函数会强制组件重新渲染。
useSafeState: 用法与useState 完全一样,但是在组件卸载后异步回调内的 setState 不再执行,避免因组件卸载后更新状态而导致的内存泄漏。

子组件中

1.在index.tsx文件中

interface EllipsisProp {
  width?: number // 宽度 默认百分之百
  text: string // 文本内容
  customView?: ReactDOM //自定义文本
  rows?: number // 展示几行 默认2行
}
import { useSafeState, useUpdate } from 'ahooks'
import React, { useEffect, useRef } from 'react'

const Ellipsis: React.FC<EllipsisProp> = (props) => {
  // 父组件传来的值
  const { width, text = '', customView, rows = 2 } = props
  // 设置初始文本值
  const [textView, setTextView] = useSafeState('')
  const ref = useRef<HTMLDivElement>(null)
  const updata = useUpdate()

  useEffect(() => {
    setTextView(text)
    setTimeout(() => {
     // 强制渲染
      updata()
    }, 30)
  }, [text])
  
  // 总体高度
  const scrollHeight = ref.current?.scrollHeight || 0
  // 可视高度
  const clientHeight = ref.current?.clientHeight || 0
  
  return (
    <Div
      rows={rows}
      width={width ? width + 'px' : '100%'}
      text={text}
      isExceed={scrollHeight > clientHeight + 5} // 样式判断
    >
      <div className="text_view" ref={ref}>
        {scrollHeight > clientHeight + 5 && (
          <div className="view">{customView}</div>
        )}
        <span className="text">{textView}</span>
      </div>
    </ContentArea>
  )
}
export default Ellipsis

2.在styled.ts中

import styled from 'styled-components'
const Div = styled.div<{
  width: string // 宽度
  rows: number // 行数
  text: string // 文本
  isExceed: boolean // 样式判断
}>`
  display: flex;
  .text_view {
    width: ${(p) => p.width}; 宽度 父组件传过来的高度
    line-height: 22px;
    max-height: ${(p) => p.rows * 22 + 'px'}; // 最大高度 行数* 每一行的高度
    overflow: hidden;
    font-size: 14px;
    color: #262626;
    &::before {
      content: '';
      display: ${(p) => (!p.isExceed ? 'none' : 'inline-block')}; 
      float: right;
      width: 0px;
      height: ${(p) => p.rows * 22 + 'px'};
      margin-bottom: -20px;
    }
    .text{
      whiteSpace: pre-wrap; // 保留空白符序列,但是正常地进行换行。
    }
    .view {
      position: relative;
      float: right;
      clear: both;
      &::before {
        content: '...';
        position: absolute;
        left: 1px;
        top: -2px;
        color: #333;
        transform: translateX(-100%);
      }
    }
    .views {
      clear: both;
      display: inline-block;
      margin-left: ${(p) => (p.text ? '6px' : 0)};
    }
  }
`
export { Div }
父组件调用
<Ellipsis text={'测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试'} width={319} rows={2}/>

结果:
文本省略

简单的单行文本超出最大宽度显示省略 …

<span className="font_simall">
  测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试
</span>
.font_simall {
  max-width: 200px; 最大宽度
  display: inline-block;
  overflow: hidden;
  white-space: nowrap; 强制不换行
  text-overflow: ellipsis; 省略
}

简单的多行文本超出最大宽度显示省略 …

.font_simall {
   width: 215px;
   display: -webkit-box;
   word-break: break-all;
   text-overflow: ellipsis; 
   overflow: hidden;
   -webkit-line-clamp: 2;
   -webkit-box-orient: vertical;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值