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
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);
创建项目
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状态:完成、待定、全部
代码:
本模块主要是封装一个函数组件,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事务的添加,重置等功能
图示:
代码:
主要提供两个组件,由于功能不复杂,因此代码简单,主要用于介绍本文功能
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: 核心渲染页面,结合前面几个组件完成整个功能页面的渲染
图示
代码
使用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)