React文字展开收起组件的实现示例

目录
  • 前言
  • 背景
  • 开发
    • 1.1 定义组件所需字段
    • 1.2 获取截断后的文字
    • 1.3 获取展开收起按钮
    • 1.4 展开收起逻辑
    • 1.5 完整代码
      • 1.5.1 逻辑代码
      • 1.5.2 样式代码
    • 1.6 安装使用组件
  • 资源

前言

最近想把在项目中封装的一些公用组件奉献出来,毕竟独乐乐不如众乐乐,好东西就要大家分享。这次还是来聊实战,主题就是文字展开收起组件的实现过程,这个需求在前端项目中也算常见的需求了,可能你已经在项目中使用了自己或别人封装的组件,但是这次还是希望你能耐心地看看我的实现过程,毕竟多一个思路也会让你在后续的工作中游刃有余。

背景

老规矩,实战项目必有背景。那还是先来聊聊这个文字展开收起组件产生的需求背景,需求其实就是要你把多余的文字省略显示,然后有展开收起的按钮可以操作。对,就是这么直白,上图:

上图是文字收起的图示,超过一定的字数那就收起省略显示,并出现查看全部按钮。

上图显示的就是操作了查看全部按钮之后,文字需要全部显示出来并有收起按钮。还是来看一张gif图的显示最后该组件完成后的效果,如下图:

开发

该组件还是使用React+typescript的技术栈,所以还是之前的老话,如果不是此技术栈的同学就只有参考实现思路,后续待不忙时再来提供其他技术栈对应的版本。

文字展开收起组件的开发就没有啥思考的点,就只需要在做的时候考虑一定字数这个问题,超过它截取文字并加上...,然后展开时展示所有文字即可,其它的操作基本是常规操作。话不多说,直接往下看→

1.1 定义组件所需字段

interface IndexProps {
    content: string;    // 文本内容
    maxLen?: number;   // 文字最大显示长度
    expandText?: string; // 展开按钮文字
    collapseText?: string; // 收起按钮文字
    contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定义内容
    onExpand?: (expanded: boolean) => void; // 展开、收起后触发
}

可以看到文字展开收起组件需要用到上述6个字段,其中contentcontentRender是必须传入的,否则组件会报错,其他字段皆为可选字段,需要时就传入不需要就会使用组件定义的默认值。

1.2 获取截断后的文字

获取截断后的文字,其实是根据字段maxLen来自动获取,maxLen设置的默认值为300,即超过300个文字之后就会被截断。maxLen的值是可以修改的,若你设置为200,即文字超过200就会被截取,故其为可选字段。代码如下:

/**
 * 获取截断后的文字
 * @param text
 */
const getText = (text: string): string => {
    return (text || '').slice(0, maxLen) + '...'
}

1.3 获取展开收起按钮

细心的小伙伴可以从1.1定义的字段中可以看到,其中contentRender这个字段代表的意思为自定义内容,即该组件的内容是可以自定义的。因为在设计的时候,就考虑到该组件应用的场景可能有点多,所以希望它是可以根据不同的需求场景来进行自定义的,所以该组件的render内容就只有此方法,如下:

return (
    <>{contentRender(body, getExpandBtn())}</>
)

contentRender方法其实接收两个参数:text代表文本内容,其实就是传入的content,只不过它会根据判断条件判断是否被截取;在组件加载时,就会对其进行如下判断:

useEffect(() => {
    let contentBody = content || '';
    if (contentBody.length > maxLen) {
        contentBody = getText(contentBody);
        setShowBtn(true);
    }
    setBody(contentBody);
    return () => {
        setExpanded(false);
        setShowBtn(false);
    }
}, [content]);

通过上述代码可以获取到需要渲染的文本内容,然后将其赋值给body,即它就是contentRender方法接收的第一个参数。

而第二个参数handler其实就是这里将要说的,获取展开收起按钮的方法。如下:

/**
 * 获取展开收起按钮
 * @param status
 */
const getExpandBtn = (): React.ReactNode => (
    showBtn ? (
        <span
            className="custom-text-expanded-handler"
            onClick={() => expandToggle(!expanded)}
        >{expanded ? collapseText : expandText}
        </span>
    ) : null
)

从上可以看到,所谓的自定义其实就是我们可以对参数text进行自定义,可以将其使用div包裹,或者对其样式进行自定义皆是可以的。而在我们的项目中,则是又写一个名词解释组件对其自定义,名词解释组件可在下篇文章中简述。

1.4 展开收起逻辑

所谓的展开收起逻辑其实就是让文字省略展示或者全部展示,而在这个过程中可以使用暴露出去的onExpand方法做其他逻辑操作,代码如下:

/**
 * 展开、收起
 * @param status
 */
const expandToggle = (status: boolean) => {
    let text = status ? content : getText(content);
    setExpanded(status);
    setBody(text);
    onExpand(status);
}

1.5 完整代码

好了,通过上述的简单介绍,组合代码可以得到文字展开收起组件完整代码。

1.5.1 逻辑代码

创建index.tsx文件,并写入如下所示代码:

import * as React from 'react';
import {useEffect, useState} from "react";
import './index.scss';

interface IndexProps {
    content: string;    // 文本内容
    maxLen?: number;   // 文字最大显示长度
    expandText?: string; // 展开按钮文字
    collapseText?: string; // 收起按钮文字
    contentRender: (text: string, handler: React.ReactNode) => React.ReactNode; // 自定义内容
    onExpand?: (expanded: boolean) => void; // 展开、收起后触发
}

/**
 * 自定义文字展开收起组件
 * @param props
 * @constructor
 */
const TextExpand = (props: IndexProps) => {
    const {
        content,
        maxLen = 300,
        expandText = '查看全部',
        collapseText = '收起',
        contentRender = (text: string, handler: React.ReactNode) => {},
        onExpand = (expanded: boolean) => {},
    } = props;
    const [body, setBody] = useState<any>(null);
    const [expanded, setExpanded] = useState<boolean>(false);
    const [showBtn, setShowBtn] = useState<boolean>(false);

    useEffect(() => {
        let contentBody = content || '';
        if (contentBody.length > maxLen) {
            contentBody = getText(contentBody);
            setShowBtn(true);
        }
        setBody(contentBody);
        return () => {
            setExpanded(false);
            setShowBtn(false);
        }
    }, [content])

    /**
     * 获取截断后的文字
     * @param text
     */
    const getText = (text: string): string => {
        return (text || '').slice(0, maxLen) + '...'
    }

    /**
     * 获取展开收起按钮
     * @param status
     */
    const getExpandBtn = (): React.ReactNode => (
        showBtn ? (
            <span
                className="custom-text-expanded-handler"
                onClick={() => expandToggle(!expanded)}
            >{expanded ? collapseText : expandText}
            </span>
        ) : null
    )

    /**
     * 展开、收起
     * @param status
     */
    const expandToggle = (status: boolean) => {
        let text = status ? content : getText(content);
        setExpanded(status);
        setBody(text);
        onExpand(status);
    }

    return (
        <>{contentRender(body, getExpandBtn())}</>
    )
}

export default TextExpand;

1.5.2 样式代码

创建index.scss文件,同样写入如下代码即可:

.custom-text-expanded-handler {
    margin-left: 6px;
    color: #545FD6;
    &:hover {
        color: #1890ff;
        cursor: pointer;
    }
}

1.6 安装使用组件

组件写好,那就来使用它。该组件已经发布到npm上了,所以小伙伴们可以到npm上查看并下载,也可以通过如下命令进行安装使用:

npm i react-text-expand-collapse 或 yarn add react-text-expand-collapse

安装好之后,在项目中引用使用:

// 引入组件
import TextExpand from 'react-text-expand-collapse/src/index';

// 使用
<div style={{
  width: 500,
  margin: '10px auto 0',
  color: '#333',
  fontSize: '12px',
  textAlign: 'left',
  backgroundColor: '#fff'
}}>
  <TextExpand
    content={str}
    maxLen={100}
    contentRender={(text: string, handler: any) => {
      return (
          <>
            <span>{text}</span>
            {handler}
          </>
      )
    }}
  />
</div>

最后实现效果,如下图:

如果你有需求需要用到该组件但不想去下载安装,那你就直接把这个完整代码拷到你的项目中去,直接创建文件引用即可。(最好还是下载使用吧,这样对作者有一定的支持,作者也会挺开心的^_^)

最后,文字展开收起组件的开发思路和实现就介绍完了,其实这个需求还是挺常见的,如果你以后遇到这样的需求就来看看我的这篇文章吧,3Q

资源

npm地址:react-text-expand-collapse

github仓库:https://github.com/Jacky010/react-text-expandCollapse

到此这篇关于React文字展开收起组件的实现示例的文章就介绍到这了,更多相关React文字展开收起内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • React实现复杂搜索表单的展开收起功能

    给时间时间,让过去过去. 上节我们写过了[搜索]表单,以及查询.重置功能.本节对于需要展开收起效果的查询表单 进行概述,主要涉及前端样式知识. 样式效果如下: 思路:在Search组件中定义两个组件renderAdvancedForm,renderSimpleForm,其中renderSimpleForm中只有五个查询选项,而在renderAdvancedForm包含所有的搜索选项.点击'展开''收起'按钮调用onClick={toggleForm}切换form显示样式即可. 1. 写rende

  • vue和react等项目中更简单的实现展开收起更多等效果示例

    前言 本文题目中虽然写有vue和react,但是并非vue和react相关知识,而是最基本的html5和css3的一些知识,之所以写vue,是因为我最近项目中用到了类似效果,我用vue相关知识实现并不雅观,用html5和css3实现,则更加完美. 项目案例 项目中有如下效果: 好多展开收起,对于这个的实现,我一开始用了vue一些比较挫的dom操作,就是父元素toggleClass一个类名,进行子元素的显示和隐藏. 由于这个方法是通用方法,项目中好多地方使用,代码大概如下: toggleShow(

  • React文字展开收起组件的实现示例

    目录 前言 背景 开发 1.1 定义组件所需字段 1.2 获取截断后的文字 1.3 获取展开收起按钮 1.4 展开收起逻辑 1.5 完整代码 1.5.1 逻辑代码 1.5.2 样式代码 1.6 安装使用组件 资源 前言 最近想把在项目中封装的一些公用组件奉献出来,毕竟独乐乐不如众乐乐,好东西就要大家分享.这次还是来聊实战,主题就是文字展开收起组件的实现过程,这个需求在前端项目中也算常见的需求了,可能你已经在项目中使用了自己或别人封装的组件,但是这次还是希望你能耐心地看看我的实现过程,毕竟多一个思

  • vue控制多行文字展开收起的实现示例

    这里讲一下,如何使用vue控制多行文字展开收起(也叫控制文字展开隐藏). 效果: 这里设置了控制三行,如果超过三行会展示,"显示更多" 超出文字显示省略号.点击"显示更多"会展开所有文案,按钮变成"收起" (未超出三行的时候) (展开) (收起) 代码实现: <template> <div> <p class="m-content overflow-line" id="J_descrip

  • 可定制React自动完成搜索组件Turnstone实现示例

    目录 正文 特点 如何使用它 1.安装并导入Turnstone 2.基本使用方法 3.默认的组件道具 预览 正文 一个高度可定制的.易于使用的React自动完成搜索组件. 特点 轻量级的React搜索框组件 用可定制的标题将来自多个API或其他数据源的搜索结果分组 指定列表框选项的最大数量,以及每组的加权显示比例 用你自己的React组件完全定制列表框选项.添加图片.图标.额外的子选项.按组或索引的不同视觉处理等等...... 在输入的文本下面显示typeahead自动建议文本 使用各种CSS方

  • React实现数字滚动组件numbers-scroll的示例详解

    目录 一.设计原理 二.实现方式 三.使用方式 四.参数说明 数字滚动组件,也可以叫数字轮播组件,这个名字一听就是非常普通常见的组件,第一反应就是想找找网上大佬的东西顶礼膜拜一下,这一搜,还真是没找到趁手的╮(╯▽╰)╭. 最近接了大屏的需求,数字滚动肯定是免不了的,所以开始撸袖子,造轮子了( numbers-scroll ). 首先给大家看下轮子的效果吧: 一.设计原理 如果要做到数字滚动效果,就一定要让数字有从下往上移动的感觉.如果只是纯粹的数字变化,显示出来的效果就会比较普通了,没有什么视

  • ES6下React组件的写法示例代码

    本文主要跟大家分享了ES6下React组件的写法示例,下面来一起看看详细的介绍: 一:定义React组件 class Hello extends React.Component { render() { return <h1>Hello, {this.props.value}</h1>; } } 二:声明prop类型与默认prop class Hello extends React.Component { // ... } Hello.propTypes = { value: Re

  • React Native 截屏组件的示例代码

    React Native 截屏组件:react-native-view-shot,可以截取当前屏幕或者按照当前页面的组件来选择截取,如当前页面有一个图片组件,一个View组件,可以选择截取图片组件或者View组件.支持iOS和安卓. 安装方法 npm install react-native-view-shot react-native link react-native-view-shot 使用示例 captureScreen() 截屏方法 截取当前屏幕,跟系统自带的截图一致,只会截取当前屏幕

  • React Native悬浮按钮组件的示例代码

    React Native悬浮按钮组件:react-native-action-button,纯JS组件,支持安卓和IOS双平台,支持设置子按钮,支持自定义位置和样式和图标. 效果图 安装方法 npm i react-native-action-button --save react-native link react-native-vector-icons 因为用到了react-native-vector-icons图标组件,需要做下link.如果你项目中已经使用了react-native-ve

  • 一个基于react的图片裁剪组件示例

    开始 写了一年多vue,感觉碰到了点瓶颈,学习下react找找感觉.刚好最近使用vue写了个基于cropperJS的图片裁剪的组件,便花费了几个晚上的功夫用react再写一遍.代码地址 项目是使用create-react-app来开发的,省去了很多webpack配置的功夫,支持eslint,自动刷新等功能,使用前npm install并npm start即可.推荐同样是新学习react的人也用用看. 项目写的比较简陋,自定义配置比较差,不过也是完成了裁剪图片的基本功能,希望可以帮助到初学reac

随机推荐