前端大屏系统解决方案

430 阅读1分钟

项目背景

由于公司需要配合政府统一管理辖区的所有单车及电单车,需要开发一套大而全的指挥中心大屏系统

系统设计

image.png

技术选型

  • 前端框架 React hooks
  • 组件库 Ant Design
  • 状态管理 Redux
  • 样式适配 Sass + Rem
  • 工具类 Axios、Uuid

具体实现

模块Key声明

import * as actions from './store/actionCreator'; 
export default { 
    manifest: [ 'Test1', 'Test2' ], 
    actions 
}

根页面

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import Config from './schedule/index';
import styles from './index.module.scss';
import Modules from './components/Modules';
import { HomeContext } from './context/index';
import { v4 as uuidv4 } from 'uuid';

let index = 0;
let loopDelay = 500000;
let { manifest = [] } = Config;
const { actions = {} } = Config;
const Home = function () {
  const dispatch = useDispatch();
  let status = [];
  let RenderDelay = 6000;

  useEffect(() => {
    init();
  }, []);

  // 启动第一个模块渲染  
  const init = () => {
    dispatch(actions[`change${manifest[0]}`](uuidv4()));
  };

  // 执行回调,开启下一个任务  
  const onLoaded = (key: string) => {
    try {
      if (!status.includes(key)) {
        status.push(key); index++;
        if (index < manifest.length) {
          setTimeout(() => {
            dispatch(actions[`change${manifest[index]}`](uuidv4()));
          }, RenderDelay);
        } else {
          // 在这里执行定时更新数据
          loopRequest();
        }
      }
    } catch (error) {
      console.log(error);
    }
  };
  const reset = () => {
    index = 0;
    status = [];
    manifest.forEach((key) => {
      dispatch(actions[`change${key}`](0));
    });
  };
  const loopRequest = () => {
    setTimeout(() => {
      reset();
      init();
    }, loopDelay);
  };
  return (
    <div className={styles.container}>
      <section className={styles.content} >
        {/* 绑定各个模块执行完的回调 */}
        <HomeContext.Provider value={{ callback: onLoaded, }}        >
          <section>
            <Modules />
          </section>
        </HomeContext.Provider>
      </section>
    </div>);
};
export default Home;

子模块

import { memo, useEffect, useState, useContext } from 'react'; 
import { useSelector } from 'react-redux'; 
import { HomeContext } from '@/pages/Basement/context';
const Test1 = memo(() => {
  const { callback } = useContext(HomeContext);
  const schedule = useSelector((state) => state.getIn(['Test1']));
  const [name, setName] = useState('')
  useEffect(() => {
    if (schedule !== 0) {
      init();
    } else {
      reset();
    }
  }, [schedule]);
  const reset = () => {
    setName('');
  };
  const init = async () => {
    setName(`I'm test1 module`)
    callback('Test1');
  };
  return (
    <section >
      {name}
    </section>
  );
});

const Test2 = memo(() => {
  const { callback } = useContext(HomeContext);
  const schedule = useSelector((state) => state.getIn(['Test2']));
  const [name, setName] = useState('');
  useEffect(() => {
    if (schedule !== 0) {
      init();
    } else {
      reset();
    }
  }, [schedule]);
  const reset = () => {
    setName('');
  };
  const init = async () => {
    setName(`I'm test2 module`)
    callback('Test2');
  };
  return (
    <section >
      {name}
    </section>
  );
});

const Modules = () => {
  return (
    <>
      <Test1 />
      <Test2 />
    </>
  )
}

export default Modules;