美文网首页JavaScript 进阶营让前端飞技术干货
一个无限层级树形选择器的动态搜索高亮function

一个无限层级树形选择器的动态搜索高亮function

作者: Ryan_JS | 来源:发表于2018-02-02 18:54 被阅读178次

    需求

    如下图的一个带搜索功能的树形选择器,搜索的时候隐藏掉没有关联的节点,同时,如果子节点中有命中的,则不隐藏。

    示例图,来自Antd

    思路

    1. 首先,这个树形选择器的层级并不能确定,这里考虑用一个方法递归调用来实现。
    2. 递归实现的思路应该从最后一个子节点思考,并且父节点在子节点命中了搜索词的时候也要显示。

    代码实现

    最后实现的代码就如下,觉得还是比较有趣的,也算是写了很久无聊的业务代码写点逻辑换个心情吧。

    铺垫一下,data的数据结构:

    treeData: PropTypes.arrayOf(
      PropTypes.shape({
        id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
        name: PropTypes.string,
        subTrees: PropTypes.arrayOf(
          PropTypes.shape({
            id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
            name: PropTypes.string,
            iconClassName: PropTypes.string,
          })
        ),
      })
    ),
    

    递归function代码如下:

      renderTreeNodes = data => {
        const { searchValue, isSearchFilter } = this.props;
    
        const returnData = [];
        for (const item of data) {
          const { name } = item;
    
          let title = this.highlightSearchValue(name, searchValue);
          if (item.iconClassName) {
            title = (
              <span>
                <i className={`${ICON_FONT} ${item.iconClassName}`} />
                {title}
              </span>
            );
          }
          if (item.subTrees) {
            const subTreeNodes = this.renderTreeNodes(item.subTrees);
            if (
              (isSearchFilter && subTreeNodes.length > 0) ||
              (!isSearchFilter || name.indexOf(searchValue) > -1)
            ) {
              // if on searchFilter mode, push the parent node when child nodes exist
              returnData.push(
                <TreeNode key={item.id} title={title}>
                  {subTreeNodes}
                </TreeNode>
              );
            }
          } else if (!isSearchFilter || name.indexOf(searchValue) > -1) {
            // if on searchFilter mode, push the last child node only when the node is match the search value
            // otherwise, push the node anyway
            returnData.push(<TreeNode key={item.id} title={title} />);
          }
        }
        return returnData;
      };
    

    文本怎么高亮?实现如下:

      highlightSearchValue = (name, searchValue) => {
        if (!searchValue) {
          return <span>{name}</span>;
        }
    
        const index = name.indexOf(searchValue);
        const beforeStr = name.substr(0, index);
        const afterStr = name.substr(index + searchValue.length);
        return index > -1 ? (
          <span>
            {beforeStr}
            <span className={cx('highlight-search-value')}>{searchValue}</span>
            {afterStr}
          </span>
        ) : (
          <span>{name}</span>
        );
      };
    

    相关文章

      网友评论

        本文标题:一个无限层级树形选择器的动态搜索高亮function

        本文链接:https://www.haomeiwen.com/subject/qpgezxtx.html