首页 > 其他分享 >React文本溢出组件封装以及高亮提示

React文本溢出组件封装以及高亮提示

时间:2024-05-09 16:56:49浏览次数:13  
标签:封装 string React length Abbr 组件 高亮 const

React文本溢出组件封装以及高亮提示

Abbr 组件:使用场景:

  1. 当我们需要设置支持最大行数时进行省略展示
  2. 当我们需要设置支持设置超过多少字符进行省略展示
  3. 当我们需要设置支持关键字高亮展示(有点问题,当关键字被裁剪成...之后,就无法高亮)
  4. 当我们需要支持忽略大小写高亮
  5. 当我们需要支持ToolTip展示全部文本,且可以在toolTip上进行关键字高亮

Abbr 组件tsx

 import { Tooltip } from "antd";
import React from "react";
import "./index.less";
import { finxAllIndex, returnRenderName } from "./tools";

interface AbbrTextProps {
  /* 需要展示的文本 */
  text: string;
  /* 截取的长度 */
  length?: number;
  /* 设置行数 */
  line?: number;
  /* 设置样式 */
  className?: string;
  /* 高亮关键字 */
  keyWord?: string;
  /* 是否在tooltip中也高亮展示 默认不展示 */
  showTooltipHighlight?: boolean;
  /* 主题 */
  theme?: "default" | "warning" | "error" | "success";
  /* 是否忽略大小写 */
  ignoreCase?: boolean;
}
const AbbrText: React.FC<AbbrTextProps> = ({
  text,
  length,
  line,
  className,
  keyWord = "",
  showTooltipHighlight = false,
  theme = "default",
  ignoreCase = false,
}) => {
  let displayText: JSX.Element | string = text;
  let style = {};
  let showTooltip = false;

  /* 如果有高亮的关键字 */
  const heightKeyWord = (
    readyText: string,
    keyWord: string,
    showAll?: boolean
  ): JSX.Element => {
    /* 目标结果在字符串中的所有索引 */
    const findAllIndex = finxAllIndex(readyText, keyWord, ignoreCase);
    /* 高亮之后标签 */
    const renderName = returnRenderName(readyText, keyWord, findAllIndex, {
      theme,
    });
    const renderText = (
      <>
        {renderName}
        {!showAll && length && text.length > length && <span>...</span>}
      </>
    );
    return renderText;
  };

  if (length && text.length > length) {
    displayText = text.substring(0, length);
    showTooltip = true;
  } else if (line) {
    style = {
      display: "-webkit-box",
      "-webkit-box-orient": "vertical",
      overflow: "hidden",
      textOverflow: "ellipsis",
    };
  }
  displayText = heightKeyWord(displayText, keyWord);

  /* length 优先级大于line ,同时设置length 生效 */
  if (length && line) {
    console.warn("Abbr组件警告⚠️:length 和 line 同时设置时,length 优先级高");
  }

  // 当文本被截短或者设置了行数限制时显示提示
  const content = (
    <span
      className={`abbrtext ${className}`}
      style={{ ...style, WebkitLineClamp: line, lineClamp: line }}
    >
      {displayText}
    </span>
  );

  return (
    <Tooltip
      title={
        (showTooltip || line) && showTooltipHighlight
          ? heightKeyWord(text, keyWord, true)
          : text
      }
    >
      {content}
    </Tooltip>
  );
};

AbbrText.defaultProps = {
  length: undefined,
  line: 1,
  className: "",
};

export default AbbrText;

Abbr 组件less

.abbrtext {
    word-break: break-all;
    width: fit-content;
}

.hightlight {
    &.default {
        color: blue;
    }

    &.success {
        color: green;
    }

    &.error {
        color: red;
    }

    &.warning {
        color: orange;
    }

}

Abbr 组件工具函数

 /**
 * @param str 字符串
 * @param itemStr 目标字符串
 * @param ignoreCase 是否忽略大小写
 * @returns 目标结果在字符串中的所有索引
 */
export const finxAllIndex = (
  str: string,
  itemStr: string,
  ignoreCase = false
) => {
  // 初始化结果数组
  const result = [];
  // 遍历字符串,寻找目标项并记录索引
  for (let i = 0; i <= str.length - itemStr.length; ) {
    let index = str.indexOf(itemStr, i);
    if (ignoreCase) {
      index = str.toLocaleLowerCase().indexOf(itemStr.toLocaleLowerCase(), i);
    }
    if (index !== -1) {
      // 更简洁的判断条件
      result.push(index);
      i = index + itemStr.length; // 更新i值
    } else {
      i++;
    }
  }
  return result;
};

/**
 * @param str 字符串
 * @param keyWords 关键字
 * @param allIndexArray 所有索引
 * @param config 配置
 * @param config.theme 主题
 * @returns 高亮之后标签
 */
export const returnRenderName = (
  str: string,
  keyWords: string,
  allIndexArray: Array<number>,
  config?: {
    theme?: "default" | "warning" | "error" | "success";
  }
) => {
  const { theme = "default" } = config || {};
  if (allIndexArray.length === 0) {
    return str;
  }
  /* 最终结果 */
  let res: string | JSX.Element | null = null;
  let loopindex = 0;
  const loop = (index = 0): string | JSX.Element => {
    res = (
      <>
        {res}
        {str.substring(index, allIndexArray[loopindex])}
        <span className={`hightlight ${theme}`}>
          {str.substring(allIndexArray[loopindex], keyWords.length)}
        </span>
      </>
    );
    loopindex++;
    if (allIndexArray.length <= loopindex) {
      res = (
        <>
          {res}
          {str.substring(allIndexArray[loopindex - 1] + keyWords.length)}
        </>
      );
      return res;
    } else {
      return loop(allIndexArray[loopindex - 1] + keyWords.length);
    }
  };
  loop();
  return res;
};

Abbr 组件测试

import React from "react";
import AbbrText from "./components/Abbr";

function App() {
  return (
    <>
      <AbbrText
        text="Hello World"
        keyWord="hello"
        length={10}
        showTooltipHighlight
        ignoreCase
        theme="warning"
      />
    </>
  );
}

export default App;

效果图

img

标签:封装,string,React,length,Abbr,组件,高亮,const
From: https://www.cnblogs.com/gjzsa/p/18182625

相关文章

  • react 性能优化
    一纯组件1使用shouldComponentUpdate对先前的状态和props数据与下一个props或状态相同,如果两次的结果一直,那么就returnfalse使用纯净组件,pureComponentPureComponents负责shouldComponentUpdate——它对状态和props数据进行浅层比较(shallowcomparison),如果先前......
  • react里面bind与箭头函数
    bind由于在类中,采用的是严格模式,所以事件回调的时候,会丢失this指向,指向undefined,需要使用bind来给函数绑定上当前实例的this指向;箭头函数的this指向上下文,所以永久能拿到当前组件实例,this指向,我们可以完美的使用箭头函数来替代传统事件处理函数的回调箭头函数class......
  • 面向对象的三大特性、封装的介绍及属性、装饰器property、员工管理系统
    【一】面向对象的三大特性封装:封装指的就是把数据与功能都整合到一起继承多态【二】什么是封装封装是对具体对象的一种抽象意思就是将某部分功能和代码隐藏起来,在程序外边看不到,只能在程序内部使用【三】为什么要封装?封装数据的主要原因是:保护隐私(把不想别人......
  • react理论总结1
     1)对react的理解(特点)1,Jsxjs+xml,是对js语法的扩张,需要通过babel.js的编译转化成浏览器可以解析的普通js对象2,虚拟dom。相当于在js和真实dom之间的缓存,state改变调用render函数会重新生成新的虚拟dom树,通过diff算法计算出新旧dom差异 只能差异部分更新到真实的dom,减少......
  • 使用同事封装好的table(使用el-table),修改表头背景色怎么实现
    花了一下午时间基本功还是比较差参考博客1首先,要修改表头颜色,需要el-table的属性:header-cell-style可以这样写:header-cell-style="{background:'#409EFF',color:'#409EFF'}"而我有两个点需要考虑1)只有部分表头需要修改颜色2)同事封装的组件,对背景颜色使用了!important解决......
  • UIOTOS前端零代码应用 蓝图连线+嵌套封装 实现MQTT输入0、1切换门禁开和关
    目标通过连线+嵌套封装,实现MQTT数据推送前端控制门禁开关最终效果实现过程步骤1:新建一个页面,在工具函数input输入两个门禁的开关图标地址,再通过连线和解析实现输0、1切换图标。 步骤2:再插入图片按钮,通过连线和解析,把工具函数的输出传递给图片按钮组件的path属性。 步骤......
  • react ts 项目如何配置路径别名?
    tsconfig.json{"compilerOptions":{"baseUrl":".",//路径配置"paths":{"@/*":["src/*"]},"target":"ES2020","lib":[......
  • 【HarmonyOS Next】多线程网络请求简单封装
    importhttpfrom'@ohos.net.http';import{taskpool}from'@kit.ArkTS';exportclassRequest{staticasyncget(url:string,header?:Object,expectDataType:http.HttpDataType=http.HttpDataType.OBJECT):Promise<Object>{......
  • React Hooks 入门教程【阮一峰】
    组件类的缺点React的核心是组件。早前版本,组件的标准写法是类。//一个简单的组件类importReact,{Component}from"react";exportdefaultclassButtonextendsComponent{constructor(){super();this.state={buttonText:"Clickme,please"};......
  • TS — 在React中使用TS(基础使用)
    在React中使用TypeScript(TS)是一种很常见的做法,因为TypeScript提供了静态类型检查和其他一些有用的功能,可以帮助您更好地开发和维护React应用。1.原始组件://SimpleComponent.jsimportReactfrom'react';constSimpleComponent=({name})=>{return<div>Hel......