React+Mobx+Antd前端项目实战

React+Mobx+Antd前端项目案例

一、React简介
  • React 起源于 Facebook 的内部项目,目前已经开源。

  • 特点:

    • 声明式设计
    • 高效、灵活
    • 支持Jsx语法扩展,tsx通过–template typescript 创建也可以支持
    • 使用组件概念,通过组件构建整个前端项目生态,OOP思想,容易维护和复用
    • 单向响应的数据流、绑定简单,易理解
    • 虚拟Dom,更加高效
  • 安装 create-react-app

    npm install -g create-react-app

    yarn add -g create-react-app

  • 创建项目(npm npx yarn都可以,方式一样)

    create-react-app app-name 注意命名方式

    npm create-react-app app-name

    yarn create react-app app-name

二、Mobx简介:1. MobX 介绍 · MobX 中文文档
  • react状态管理

    在react项目中,作为前端项目的核心,就是各个行为、动作等状态的维护、同步管理,被广泛使用的有redux和mobx,两者各有特点,均可以实现react项目中的状态管理

  • mobx简介

    MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展(官方)。

    • React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。
    • React 提供了优化UI渲染的机制, 这种机制就是通过使用虚拟DOM来减少昂贵的DOM变化的数量。MobX 提供了优化应用状态与 React 组件同步的机制,这种机制就是使用响应式虚拟依赖状态图表,它只有在真正需要的时候才更新并且永远保持是最新的。
  • mobx核心要点

    • 定义状态并使其可观察

      // 通过observable可以轻松创建一个可监听、观察的状态
      import {observable} from 'mobx';
      var appState = observable({
          timer: 0
      });
      
    • 创建视图以响应状态的变化

      // observer: 创建观察者,可以监听状态并做出响应、更新
      import {observer} from 'mobx-react';
      
      @observer
      class TimerView extends React.Component {
          render() {
              return (
                  
              );
          }
         // 更新状态
          onReset() {
              this.props.appState.resetTimer();
          }
      };
      
    • 更新、维护状态

      // action: 行为、动作定义,用于更新状态
      appState.resetTimer = action(function reset() {
          appState.timer = 0;
      });
      
      setInterval(action(function tick() {
          appState.timer += 1;
      }), 1000);
      
三、Antd组件库
  • Ant Design 是一个致力于提升『用户』和『设计者』使用体验的设计语言 ;旨在统一中台项目的前端 UI 设计,屏蔽不 必要的设计差异和实现成本,解放设计和前端的研发资源; 包含很多设计原则和配套的组件库。
  • 地址:Ant Design - 一套企业级 UI 设计语言和 React 组件库 (gitee.io)
四、Demo-TodoApp
  • 创建项目

    yarn create react-app Todo-App --template typescript 
    // Todo-App是项目名称
    // --template typescript 使用typescript
    
  • 项目核心结构

    .
    |-- MToDo // Mobx实现Todo的目录
    |   |-- MFilter // 过滤操作组件目录
    |   |   |-- Filter.tsx // 过滤操作组件
    |   |   `-- style.css // css样式
    |   |-- TodoOperate.tsx // 添加等操作组件
    |   |-- TodoView.tsx // Todo页面渲染组件
    |   `-- style.css // css组件
    |-- MTodoApp.tsx // MTodoApp组件,对外暴露
    |-- model.ts  // 存放交互数据模型
    `-- todoStore.ts // store存储模型
    ...
    index.tsx //位于最外层的入口文件
    
    
  • 功能组件介绍

    • todoStore.ts:核心交互数据中心,用于store存储模型,行为定义,供给全局共享和方法调用,是整个项目的数据核心

      @observable: 创建被监听的对象

      @action: 数据模型相应是操作方法

      /* 文件目录 store/index.js */
      
      import {observable, action, makeObservable} from 'mobx';
      import moment from "moment";
      import {FilterTypes, setVisibleTodos, TodoModel} from "@/pages/Mobx-ToDo/model";
      
      class TodoStore {
          constructor() {
              makeObservable(this); //mbox 6后需要添加这个组件才会更新
          }
      
          @observable // table 加载状态
          loading: boolean = false;
          @observable // 事件列表长度
          todoLen = 0;
          @observable // 事件列表
          todos:TodoModel[] = [];
      
          // Filter组件store状态
          @action filterTodo(filter:string) {
              if (filter === ""){
                  filter = FilterTypes.ALL
              }
              const newTodos = setVisibleTodos(filter, this.todos);
              this.loading = true;
              return newTodos;
          }
      
          // 添加todo事务方法
          @action addTodo(todo: TodoModel) {
              this.todos.push(todo);
              this.todoLen++;
              this.loading = false;
          }
         // 更新todo事务方法
          @action updateTodo = (todo:TodoModel, checked:boolean) => {
              this.todos.forEach((value,index,) => {
                  if (value.id === todo.id) {
                      this.todos[index].completed = checked;
                  }
              });
              this.loading = false;
          }
         // 删除todo事务方法
          @action deleteTodo(todo: TodoModel) {
              this.todos.forEach((value,index,) => {
                  if (value.id === todo.id) {
                     delete this.todos[index];
                     this.todoLen--;
                  }
              });
              this.loading = false;
          }
          // 重置清空数据
          @action resetTodo() {
              this.todos = [];
              this.todoLen = 0;
              this.loading = false;
          }
         // 触发实时更新渲染
          @action getNow() {
              // 设置阻止实时刷新,否则会消耗CPU资源
              this.loading = false;
          }
      }
      
      const todoStore = new TodoStore()
      
      setInterval(() => {
          todoStore.getNow()
      })
      
      export default todoStore;
      
    • model.ts: 基本数据模型、依赖行为定义

      1.定义store操作的对象数据结构,以及相关的依赖方法

      2.是整个功能的操作对象模型中心,提供给store操作

      
      export const ADD_TODO:string = 'TODO_ADD';
      export const UPDATE_TODO:string = 'TODO_UPDATE';
      export const REMOVE_TODO:string = 'TODO_REMOVE';
      export const RESET_TODO:string = 'TODO_RESET';
      
      export const SET_FILTER = 'FILTER/SET';
      
      // 全局变量
      export const FilterTypes = {
          ALL: '全部',
          COMPLETED: '已完成',
          UNCOMPLETED: '未完成'
      }
      
      export const setFilter = (filterType:string) => ({
          type: SET_FILTER,
          filter: filterType
      });
      
      export interface TodoModel {
          id?: number;
          key?: number;
          title?: string;
          completed: boolean;
          type: string;
          colorType?: string
      }
      
      export const setVisibleTodos = (filter:string, todos:TodoModel[]) => {
          switch (filter) {
              case FilterTypes.ALL:
                  return todos.filter((item:TodoModel) => item.completed||!item.completed);
              case FilterTypes.COMPLETED:
                  return todos.filter((item:TodoModel) => item.completed);
              case FilterTypes.UNCOMPLETED:
                  return todos.filter((item:TodoModel) => !item.completed);
              default:
                  return todos;
          }
      }
      
    • MTodoApp:对外暴露todoView组件,一般是index.tsx(用户自行更改)

      1.对外暴露功能,外部访问的门户

      2.可以支持/提供懒加载功能,如代码所示

      import {lazy} from "react";
      
      const TodoTable = lazy(() =>
          import('@/pages/Mobx-ToDo/MToDo/TodoView')
      )
      
      export default TodoTable;
      
    • MFilter: 过滤组件,筛选过滤todo状态:完成、待定、全部

      图示:React+Mobx+Antd前端项目实战_第1张图片

      代码:

      本模块主要是封装一个函数组件,props绑定一个父组件的filterData方法,然后传入对应的过滤参数,进行过滤,在单击对应按钮后触发。

      css为同级目录下的页面样式调整文件

      import React from 'react';
      import {FilterTypes} from "@/pages/Mobx-ToDo/model";
      import {Button} from "antd";
      import './style.css';
      
      const FilterView = (props:any) => {
          const {filterData} = props
          return (
              

      过滤选项:

      ); } export default FilterView;
    • TodoOperate:用于todo事务的添加,重置等功能

      图示:

      React+Mobx+Antd前端项目实战_第2张图片

      代码:

      主要提供两个组件,由于功能不复杂,因此代码简单,主要用于介绍本文功能

      • OperateTodoItem:用于顶部的添加事务、重置事务

      • UpdateTodoItem: 用于选择、删除事务功能

      import React, {useState} from "react";
      import {Button, Checkbox, Form, Input} from "antd";
      import {ADD_TODO, REMOVE_TODO, RESET_TODO, UPDATE_TODO} from "@/pages/Mobx-ToDo/model";
      
      export const OperateTodoItem = (props:any) =>  {
          const {addData} = props;
          const [value, setValue] = useState("默认事项");
          const onInputChange = (event:any) => {
              setValue(event.target.value);
          }
          return (
              
      ) } export const UpdateTodoItem = (props:any) => { const {updateData, data} = props; const checkedProp = data.completed ? {checked: true} : {checked:false}; return (
      { event.preventDefault(); updateData(UPDATE_TODO, data, event.target.checked); }} />
      ) }
    • TodoView: 核心渲染页面,结合前面几个组件完成整个功能页面的渲染

      图示

      React+Mobx+Antd前端项目实战_第3张图片

      代码

      使用antd组件库,使用Table组件完成todo列表的渲染,结合FilterView,OperateTodoItem组件完成完整功能

      • 定义表格数据基本结构:columns,其中操作列使用< UpdateTodoItem / >,完成每条记录的选中、删除等功能
      • OperateTodoItem: 数据添加、重置
      • FilterView: 数据过滤
      • Table: 数据展示
      import React, {useEffect, useState} from "react";
      import {inject, observer} from "mobx-react";
      import {OperateTodoItem, UpdateTodoItem} from "@/pages/Mobx-ToDo/MToDo/TodoOperate";
      import {ADD_TODO, REMOVE_TODO, RESET_TODO, UPDATE_TODO, TodoModel, FilterTypes} from "@/pages/Mobx-ToDo/model";
      import FilterView from "@/pages/Mobx-ToDo/MToDo/MFilter/Filter";
      import './style.css'
      import {ColumnsType} from "antd/es/table";
      import {Table} from "antd";
      
      
      const TodoView = inject("store")(
          observer( (props:any)=>{
              let { store } = props
              const [dataSource,setDataSource] = useState([])
              const [filterType, setFilterType] = useState("")
      
              const columns: ColumnsType = [
                  {
                      title: "事项id",
                      dataIndex: "id",
                      key: "id",
                      align: "center",
                  },
                  {
                      title: "事项名称",
                      dataIndex: "title",
                      key: "title",
                      align: "center",
                  },
                  {
                      title: "完成状态",
                      key: "completed",
                      dataIndex: "completed",
                      align: "center",
                      render: (text:boolean, record:any, index:number) => {
                          if (text) {
                              return "完成"
                          }else {
                              return "未完成"
                          }
                      }
                  },
                  {
                      title: "类型",
                      dataIndex: "type",
                      key: "type",
                      align: "center",
                  },
                  {
                      title: "操作",
                      dataIndex: "operate",
                      key: "operate",
                      align: "center",
                      render: (text:any, record:TodoModel) => (
                          
      ) } ]; const addData = (type:string, title:string) => { switch (type) { case ADD_TODO: let index = store.todos.length>= 0? store.todos.length:0; let todo: TodoModel = { id: index, key: index, type: ADD_TODO, title: `${title}`, completed: false, colorType: "", } store.addTodo(todo) setDataSource(store.filterTodo(filterType)) break; case RESET_TODO: store.resetTodo() setDataSource(store.filterTodo(filterType)) break; default: } } const updateData = (type:any, todo: TodoModel, checked: boolean=false) => { switch (type) { case REMOVE_TODO: store.deleteTodo(todo) setDataSource(store.filterTodo(filterType)) break; case UPDATE_TODO: store.updateTodo(todo, checked) setDataSource(store.filterTodo(filterType)) break; } } const filterData = (type:string) => { if (type === ""){ type = FilterTypes.ALL } setFilterType(type) setDataSource(store.filterTodo(filterType)) } const refresh = () => { if (store.loading){ setDataSource(store.filterTodo(filterType)) } } useEffect( () =>{ refresh() } ) return ( <>
      'editable-row'} /> ) }) ) export default TodoView;
    • index.tsx

      位于最外层的入口文件

      import React from 'react';
      import ReactDOM from 'react-dom/client';
      import reportWebVitals from './reportWebVitals';
      import {Provider} from "mobx-react";
      import todoStore from "@/pages/Mobx-ToDo/todoStore";
      import MTodoApp from "@/pages/Mobx-ToDo/MTodoApp";
      
      const root = ReactDOM.createRoot(
        document.getElementById('root') as HTMLElement
      );
      root.render(
        
            
                
            
        
      );
      
      reportWebVitals();
      
      
      
    • 代码仓库:Lxy0707s/todo-app: 基于react自学的todo待办列表管理示例,包含mobx和redux版本,其中mobx版本对接了antd完成了二次美化 (github.com)

    • 你可能感兴趣的:(React/Vue前端技术栈,前端,react.js,javascript)