Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2020-03-17 实现目录结构 #11

Open
fanmingfei opened this issue Mar 17, 2020 · 2 comments
Open

2020-03-17 实现目录结构 #11

fanmingfei opened this issue Mar 17, 2020 · 2 comments

Comments

@fanmingfei
Copy link
Member

输出目录结构,目录深度最高10层,输出可折叠的效果,样式不限制。

const arr = [
  {
    "path": "src/assets/example.xlsx"
  },
  {
    "path": "src/assets/example.jpg"
  },
  {
    "path": "src/assets/example.png"
  },
  {
    "path": "src/components/File.vue"
  },
  {
    "path": "src/components/Header.vue"
  },
  {
    "path": "src/components/SenderList.vue"
  },
  {
    "path": "src/components/Step.vue"
  },
  {
    "path": "src/components/Uploader.vue"
  },
  {
    "path": "src/App.vue"
  }
]

类似:
image

@LiZhaji
Copy link

LiZhaji commented Mar 17, 2020

预览:https://code.h5jun.com/hetu/1/edit?js,output
js代码:

     const parseArr = arr => {
        const treeData = [];
        arr.forEach(item => {
          const paths = item.path.split("/");
          const fileLength = paths.length;

          let curTreeData = treeData;
          for (let i = 0; i < fileLength; i++) {
            const pathName = paths[i];
            if (i === fileLength - 1) {
              curTreeData.push({ title: pathName });
              break;
            }
            let pNode = curTreeData.find(p => p.title === pathName);
            if (!pNode) {
              pNode = { title: pathName, children: [] };
              curTreeData.push(pNode);
            }
            curTreeData = pNode.children;
          }
        });
        return treeData;
      };
      const parseTreeData = data => {
        let node = "";
        for (let i = 0; i < data.length; i++) {
          const child = data[i];
          const title = child.title;
          const children = child.children;
          // 具体文件
          if (!children) {
            node += `<li>${title}</li>`;
          } else {
            node += `
          <div class="parent"><span class="expand"></span> ${title}</div>
          <ul>
            ${parseTreeData(children)}
          </ul>`;
          }
        }
        return node;
      };
      const append = arr => {
        const tree = document.querySelector("#tree");
        const data = parseArr(arr);
        const html = parseTreeData(data);
        tree.innerHTML = html;
      };

      const bindEvent = () => {
        const toggleShow = e => {
          const node = e.target.firstElementChild
            ? e.target
            : e.target.parentNode;
          const parentNode = node.nextElementSibling;
          const icon = node.firstElementChild;

          const close = parentNode.style.display === "none";
          if (close) {
            parentNode.style.display = "block";
            icon.classList = "expand";
          } else {
            parentNode.style.display = "none";
            icon.classList = "close";
          }
        };

        const parentNodes = [...document.querySelectorAll(".parent")];
        parentNodes.forEach(node => {
          node.addEventListener("click", toggleShow);
        });
      };

      const arr = [
        {
          path: "src/assets/example.xlsx"
        },
        {
          path: "src/assets/example.jpg"
        },
        {
          path: "src/assets/example.png"
        },
        {
          path: "src/components/File.vue"
        },
        {
          path: "src/components/Header.vue"
        },
        {
          path: "src/components/SenderList.vue"
        },
        {
          path: "src/components/Step.vue"
        },
        {
          path: "src/components/Uploader.vue"
        },
        {
          path: "src/App.vue"
        }
      ];
      append(arr);
      bindEvent();

@xiaosen7
Copy link

xiaosen7 commented Mar 17, 2020

预览

        const arr = [
            {
                "path": "src/assets/example.xlsx"
            },
            {
                "path": "src/assets/example.jpg"
            },
            {
                "path": "src/assets/example.png"
            },
            {
                "path": "src/components/File.vue"
            },
            {
                "path": "src/components/Header.vue"
            },
            {
                "path": "src/components/SenderList.vue"
            },
            {
                "path": "src/components/Step.vue"
            },
            {
                "path": "src/components/Uploader.vue"
            },
            {
                "path": "src/App.vue"
            }
        ];

        const tree = createTree(arr, root);

        tree.init();

        function createTree(arr, container) {

            const cache = {};

            function mapToCache(path) {
                const layer = path.split('/'), filename = layer.pop();//src,components,Uploader.vue
                let currentCache = cache;
                for (let i = 0; i < layer.length; i++) {
                    let current = layer[i];
                    if (!currentCache[current]) {
                        currentCache[current] = {};
                    }
                    currentCache = currentCache[current];
                }
                currentCache[filename] = filename
            }

            function createUlOrLi(nodename, text, deep) {
                const node = document.createElement(nodename);
                const p = document.createElement('p');
                p.innerText = text;
                node.appendChild(p);
                node.style.marginLeft = deep * 20 + 'px';
                return node;
            }

            function createUl(text, deep) {
                return createUlOrLi('ul', text, deep);
            }

            function createLi(text, deep) {
                return createUlOrLi('li', text, deep);
            }

            function insertToUl(cache, ulNode, deep = 1) {
                for (const dirname in cache) {
                    const val = cache[dirname];
                    if (typeof val === 'object') {
                        //文件夹
                        const ul = createUl(dirname, deep);
                        ulNode.appendChild(ul);
                        insertToUl(val, ul, deep + 1);
                    } else {
                        //文件
                        const li = createLi(dirname, deep);
                        ulNode.appendChild(li);
                    }

                }
            }

            function bindHandler() {
                let dirsNode = document.querySelectorAll('ul');
                
                dirsNode = [].filter.call(dirsNode, node => node != container);
                
                dirsNode.forEach(dirNode => {

                    const p = dirNode.getElementsByTagName('p')[0];

                    const children = [...dirNode.children];

                    p.onclick = () => {

                        if (dirNode.className.includes('close')) {
                            dirNode.className = '';
                            dirNode.append(...children)
                        } else {
                            dirNode.className = 'close';
                            dirNode.innerHTML = '';
                            dirNode.appendChild(p);
                        }
                    }

                })
            }

            return {
                init(con) {

                    arr.map(o => o.path).forEach(p => mapToCache(p));

                    insertToUl(cache, container);

                    bindHandler();

                }
            }
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants