【山大智云项目日志】(五)源码分析之seahub

编程入门 行业动态 更新时间:2024-10-11 23:20:39

【<a href=https://www.elefans.com/category/jswz/34/1760589.html style=山大智云项目日志】(五)源码分析之seahub"/>

【山大智云项目日志】(五)源码分析之seahub

2021SC@SDUSC
继上次分析了主要根组件MarkDownEditor之后,我发现seafile首页还是与App.js里的内容极为相似只是App.js最终是以id="wrapper"被渲染到页面,让人误以为App.js并没有用。这里展开对App.js文件下源码的分析。
在这里第一次遇到了以下的代码形式:

return (<React.Fragment>………………</React.Fragment>);

这里先了解以下React Fragment的用法。

React.Fragment 组件能够在不额外创建 DOM 元素的情况下,让 render()
方法中返回多个元素。一个常见模式是一个组件返回多个元素。Fragments 允许你将子列表分组,而无需向 DOM 添加额外节点。理解起来就是在我们定义组件的时候return里最外层包裹的div往往不想渲染到页面,那么就要用到我们的Fragment组件了。

因为我之前接触过Vue框架,这意思应该就和vue的<template ></ template >一样不会被渲染到页面。会被框架自动剔除。
详细用法可以参考博客:

接下来看代码,先从以下引入的依赖看起,主要是src文件夹下components和pages子文件夹下的组件,因此猜测App.js是集合了各个组件功能的主要面板。首先先从组件的命名来进行初步猜测各个组件对应的功能。

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Router, navigate } from '@reach/router';
import MediaQuery from 'react-responsive';
import { Modal } from 'reactstrap';
import { siteRoot, canAddRepo, isDocs } from './utils/constants';
import { Utils } from './utils/utils';
import SystemNotification from './components/system-notification';
import SidePanel from './components/side-panel';  //引入侧边栏组件
import MainPanel from './components/main-panel';  //引入主面板组件
import DraftsView from './pages/drafts/drafts-view'; //引入草稿查看组件
import DraftContent from './pages/drafts/draft-content';
import FilesActivities from './pages/dashboard/files-activities';
import Starred from './pages/starred/starred';
import LinkedDevices from './pages/linked-devices/linked-devices';
import editUtilities from './utils/editor-utilities';   //引入文本编辑工具
import ShareAdminLibraries from './pages/share-admin/libraries'; //引入共享库页面
import ShareAdminFolders from './pages/share-admin/folders';   //引入共享文件夹
import ShareAdminShareLinks from './pages/share-admin/share-links';  //引入共享链接
import ShareAdminUploadLinks from './pages/share-admin/upload-links'; //引入共享上传链接
import SharedLibraries from './pages/shared-libs/shared-libs';     //引入公共库
import ShareWithOCM from './pages/share-with-ocm/shared-with-ocm';
import OCMRepoDir from './pages/share-with-ocm/remote-dir-view';
import MyLibraries from './pages/my-libs/my-libs';   //引入私人库
import MyLibDeleted from './pages/my-libs/my-libs-deleted'; //引入已删除的库
import PublicSharedView from './pages/shared-with-all/public-shared-view';  //猜测应该是公共视图
import LibContentView from './pages/lib-content-view/lib-content-view';
import Group from './pages/groups/group-view';   //引入组
import Groups from './pages/groups/groups-view';
import InvitationsView from './pages/invitations/invitations-view';
import Wikis from './pages/wikis/wikis';
import MainContentWrapper from './components/main-content-wrapper';

再来看App.js中与React组件生命周期有关的函数:

 componentWillMount() { //组件将要挂载时先设置侧边栏关闭。避免组件覆盖。if (!Utils.isDesktop()) {this.setState({isSidePanelClosed: true});}}componentDidMount() { //组件挂载后,将客户端URL导航到库 主要是初始化页面内容// url from client  e.g. http://127.0.0.1:8000/#common/lib/34e7fb92-e91d-499d-bcde-c30ea8af9828/// navigate to library page http://127.0.0.1:8000/library/34e7fb92-e91d-499d-bcde-c30ea8af9828/this.navigateClientUrlToLib();// e.g.  from http://127.0.0.1:8000/drafts/reviews/// get reviews// TODO: need refactor laterlet href = window.location.href.split('/');if (isDocs) {this.getDrafts();}this.setState({currentTab: href[href.length - 2]});}navigateClientUrlToLib = () =>{  //导航的实现if(window.location.hash && window.location.hash.indexOf('common/lib') != -1){ //进行位置判定let splitUrlArray = window.location.hash.split('/');   //将位置拆分成数组,分解符是‘/’let repoID = splitUrlArray[splitUrlArray.length - 2];//取出数组最后一个元素作为repoIDlet url = siteRoot + 'library/' + repoID + '/';  //拼接urlnavigate(url, {repalce: true});    }}

以下是通过修改类组件的状态进行面板操作。

  getDrafts = () => {  //直接通过设对象的方式进行状态的设置editUtilities.listDrafts().then(res => {this.setState({draftCounts: res.data.draft_counts,draftList: res.data.data,isLoadingDraft: false,});});}onCloseSidePanel = () => {  //关闭侧边面板this.setState({isSidePanelClosed: !this.state.isSidePanelClosed});}onShowSidePanel = () => { //开启侧边栏this.setState({isSidePanelClosed: !this.state.isSidePanelClosed});}

这一部分的函数通过获取url,拆分,拼接的过程值得学习,分析仍以注释的形式展现。

 onSearchedClick = (selectedItem) => {if (selectedItem.is_dir === true) {this.setState({currentTab: '', pathPrefix: []});let url = siteRoot + 'library/' + selectedItem.repo_id + '/' + selectedItem.repo_name + selectedItem.path; //拼接站点根地址,选中项目的repo_id,repo_name以及选中项的pathnavigate(url, {repalce: true}); //拼接后实现地址跳转} else { let url = siteRoot + 'lib/' + selectedItem.repo_id + '/file' + Utils.encodePath(selectedItem.path);let isWeChat = Utils.isWeChat();if (!isWeChat) {  //失败跳转到空页面let newWindow = window.open('about:blank');newWindow.location.href = url;} else {location.href = url;}}}

通过文章开头的方式进行组件的渲染: <React.Fragment>

render() {let { currentTab, isSidePanelClosed } = this.state;const home = canAddRepo ?<MyLibraries path={ siteRoot } onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /> :<SharedLibrariesWrapper path={ siteRoot } onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} />;return (<React.Fragment><SystemNotification /><div id="main"><SidePanel isSidePanelClosed={this.state.isSidePanelClosed} onCloseSidePanel={this.onCloseSidePanel} currentTab={currentTab} tabItemClick={this.tabItemClick} draftCounts={this.state.draftCounts} /><MainPanel><Router className="reach-router">{home}<FilesActivitiesWrapper path={siteRoot + 'dashboard'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><DraftsViewWrapper path={siteRoot + 'drafts'}onShowSidePanel={this.onShowSidePanel}onSearchedClick={this.onSearchedClick}><DraftContentpath='/'getDrafts={this.getDrafts}isLoadingDraft={this.state.isLoadingDraft}draftList={this.state.draftList}updateDraftsList={this.updateDraftsList}/></DraftsViewWrapper><StarredWrapper path={siteRoot + 'starred'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><LinkedDevicesWrapper path={siteRoot + 'linked-devices'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><ShareAdminLibrariesWrapper path={siteRoot + 'share-admin-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><ShareAdminFoldersWrapper path={siteRoot + 'share-admin-folders'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><ShareAdminShareLinksWrapper path={siteRoot + 'share-admin-share-links'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><ShareAdminUploadLinksWrapper path={siteRoot + 'share-admin-upload-links'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><SharedLibrariesWrapper path={siteRoot + 'shared-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><SharedWithOCMWrapper path={siteRoot + 'shared-with-ocm'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><OCMViaWebdavWrapper path={siteRoot + 'ocm-via-webdav'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><MyLibraries path={siteRoot + 'my-libs'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /><MyLibDeleted path={siteRoot + 'my-libs/deleted/'} onSearchedClick={this.onSearchedClick} /><LibContentView path={siteRoot + 'library/:repoID/*'} pathPrefix={this.state.pathPrefix} onMenuClick={this.onShowSidePanel} onTabNavClick={this.tabItemClick}/><OCMRepoDir path={siteRoot + 'remote-library/:providerID/:repoID/*'} pathPrefix={this.state.pathPrefix} onMenuClick={this.onShowSidePanel} onTabNavClick={this.tabItemClick}/><Groups path={siteRoot + 'groups'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick}/><Grouppath={siteRoot + 'group/:groupID'}onShowSidePanel={this.onShowSidePanel}onSearchedClick={this.onSearchedClick}onTabNavClick={this.tabItemClick}onGroupChanged={this.onGroupChanged}/><Wikis path={siteRoot + 'published'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick}/><PublicSharedView path={siteRoot + 'org/'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} onTabNavClick={this.tabItemClick}/><InvitationsView path={siteRoot + 'invitations/'} onShowSidePanel={this.onShowSidePanel} onSearchedClick={this.onSearchedClick} /></Router></MainPanel><MediaQuery query="(max-width: 767.8px)"><Modal zIndex="1030" isOpen={!isSidePanelClosed} toggle={this.toggleSidePanel} contentClassName="d-none"></Modal></MediaQuery></div></React.Fragment>);}
}

最后将App组件render到id为’wrapper’的元素上。

ReactDOM.render(<App />,document.getElementById('wrapper')
);

其余一些重要组件的实现也会同步更新到此篇博客。未完……

更多推荐

【山大智云项目日志】(五)源码分析之seahub

本文发布于:2024-02-13 19:04:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760453.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:山大   源码   项目   日志   seahub

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!