手写树形组件-字节面试

题目

写一个树形的前端组件,包含根节点和子节点,子节点可以展开收起,有缩进样式

解答

主要还是一个递归生成叶子结点的过程,判断有children就递归生成,没有则是叶子结点。

下面找个网上的实现:

function TreeView({
  // 使用对象解构来设置某些传入属性的默认值
  data,
  toggled = true, // 折叠按钮,是否处于折叠状态
  name = null, // 当前属性名,如果子元素是对象显示
  isLast = true, // 是否最后一个
  isChildElement = false, // 是否子元素
  isParentToggled = true // 是否被父节点折叠
}) {
  const [isToggled, setIsToggled] = React.useState(toggled);

  return (
    <div
      style={{ marginLeft: isChildElement ? 16 : 4 + "px" }}
      // 如果父折叠就隐藏
      className={isParentToggled ? styles["tree-element"] : styles.collapsed}
    >
      {/* 折叠按钮,点击设置反状态 */}
      <span
        className={
          isToggled ? styles.toggler : `${styles.toggler} ${styles.closed}`
        }
        onClick={() => setIsToggled(!isToggled)}
      />
      {name ? <strong>&nbsp;&nbsp;{name}: </strong> : <span>&nbsp;&nbsp;</span>}
      {/* 开始符 */}
      {Array.isArray(data) ? "[" : "{"}
      {/* 子元素被折叠 */}
      {!isToggled && "..."}
      {/* 渲染对象的子元素 */}
      {Object.keys(data).map((v, i, a) =>
        // 是对象,递归调用自身
        typeof data[v] == "object" ? (
          <TreeView
            data={data[v]}
            key={i}
            isLast={i === a.length - 1}
            // 子元素的属性名,对象需要显示属性名,数组不显示
            name={Array.isArray(data) ? null : v}
            isChildElement
            isParentToggled={isParentToggled && isToggled}
          />
        ) : ( // 不是对象,显示内容即可
          <p
            key={i}
            style={{ marginLeft: 16 + "px" }}
            className={isToggled ? styles["tree-element"] : styles.collapsed}
          >
            {Array.isArray(data) ? "" : <strong>{v}: </strong>}
            {data[v]}
            {i === a.length - 1 ? "" : ","}
          </p>
        )
      )}
      {/* 结束符 */}
      {Array.isArray(data) ? "]" : "}"}
      {/* 不是最后元素,加个逗号 */}
      {!isLast ? "," : ""}
    </div>
  );
}

你有好的实现方法,欢迎贴到评论区!



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部