Project address: gitee.com/khigh/khigh

Hosting platform: Gitee

Project address: khigh.giee. IO /#/

Original intention: always want to do a work of their own – blog, but some treasure to buy the server often out of the problem, the domain name needs money, the server needs money. I came up with gitee Page to host the site. Gitee hosting can only be static site, how to achieve so much article data management ~ so, old husband with JSON to manage the article list, asynchronous request JSON to generate site classification, article list, article statistics and so on, through different ways to achieve access to different articles.

Talk about technology:

React with typescript as a whole

Routing: Hash routing is used, since only one HTML is generated, it cannot automatically generate HTML for each route!! The page section uses require.context to read the file, so you don’t have to manually reference the newly written page

// ./src/App.tsx import React from "react"; import { Switch, Route, HashRouter as Router } from "react-router-dom"; // import Layout from './Layout'; import { store } from "./util"; import { Provider } from "react-redux"; const context: any = (require as any).context("./page", true, /index\.tsx/); const keys: string[] = context.keys(); const page404: any = (require as any).context("./page", false, /404\.tsx/); const keys404: string[] = page404.keys(); export default class App extends React.Component<any, any> { render() { return ( <Provider store={store}> <Router> {/* <Layout> */} <Switch> {keys.map((key: string) => { const pathArr: string[] = key .replace(/^\./, "") .replace(/\/index\.tsx$/, "") .split("/"); const path: string = pathArr.join("/") || "/"; return ( <Route key={path} path={path} exact component={context(key).default} /> ); })} {keys404.map((key: string) => { return <Route key={key} component={page404(key).default} /> })} </Switch> {/* </Layout> */} </Router> </Provider> ); }}Copy the code

Data flow part: use rematch, it is really good!!

The page CONNECT connects the data flow with higher-order components wrapped around it.

/** * @description: Decorator function for connect component and model */
type IConnectFunc = (payload: any) = > any;
export constconnectModel = ( stateFunc? : IConnectFunc, dispatchFunc? : IConnectFunc ):any= > {
    const mapState: any = stateFunc ? stateFunc : (state: any) = > ({});
    const mapDispatch: any = dispatchFunc ? dispatchFunc : (dispatch: any) = >{};return (WrapperComponent: any) = > {
        class App extends React.Component<any.any> {
            public static displayName =
                "@connect" +
                (WrapperComponent.displayName
                    ? ` (${WrapperComponent.displayName}) `
                    : "");
            public render() {
                return <WrapperComponent {...this.props} />;
            }
        }
        const connected: any = connect(
            mapState,
            mapDispatch
        )(App);

        return connected;
    };
};

/** * @description: Get store */
export const store: any = (() = > {const context: any = (require as any).context(".. /models",true, /\.ts$/);
    const keys: string[] = context.keys();
    let models: {[propName:string] :any} = {};
    keys.forEach((key: string) = > {const name: string = key.replace(/ ^ \ \//, "").replace(/\.ts$/, "");
        let mdl: any = context(key);
        mdl[name] = _.cloneDeep(mdl.default);
        delete mdl.default; models = { ... models, ... mdl }; });

    const store = init({ models });

    return store;
}) ();
Copy the code

So when you use it, as long as you decorate it, you can read the store according to the file name

// Class Props{} class State{} @connectModel((State: any) => ({location: function) {// Class Props{} class State{} @connectModel((State: any) => ({location: function); state.globalData.location, articles: state.globalData.articles, siteInfo: state.globalData.siteInfo, }), (dispatch: any) => ({ setData: dispatch.globalData.setData }) ) export default class Component extends React.Component<Props,State>{ public static defaultProps=new Props(); public state=new State(); public render(){ return <div>app</div> } }Copy the code

IO /#/codeRunne…

Write iframe to react code dynamically:

For details, see./ SRC /util/index.tsx

$("body").append(` 
      
`
); const iframe: HTMLIFrameElement = $("#code-preview-wrapper iframe") [0]; const iframeDoc = iframe.contentDocument || iframe.contentWindow.document; iframeDoc.open(); iframeDoc.write(html);// The HTML section needs to wrap the code to be run into an HTML string to load the iframe for dynamic execution iframeDoc.close(); Copy the code

IO /#/artSummar…

Using G2, dynamically generate pie charts and rectangular tree charts from the retrieved article list data.

Support insertion Insert iframe in md and show: khigh.gize. IO /#/aboutme

A functional prototype is a set of functions that run code dynamically: