├── README.md
├── .gitignore
├── react-learn
├── src
│ ├── components
│ │ └── common
│ │ │ ├── ThreeLayout
│ │ │ ├── README.md
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ │ ├── Banner
│ │ │ ├── img
│ │ │ │ ├── 1.jpg
│ │ │ │ ├── 2.webp
│ │ │ │ ├── 3.jpg
│ │ │ │ ├── 4.jpg
│ │ │ │ └── 5.webp
│ │ │ ├── index.css
│ │ │ ├── SwitchDot
│ │ │ │ ├── index.css
│ │ │ │ └── index.js
│ │ │ ├── Test.js
│ │ │ ├── SwitchArrow
│ │ │ │ ├── index.css
│ │ │ │ └── index.js
│ │ │ ├── ImgContainer
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ │ ├── Modal
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ │ ├── Select
│ │ │ ├── README.md
│ │ │ ├── Test.js
│ │ │ └── index.js
│ │ │ ├── RadioBoxGroup
│ │ │ ├── README.md
│ │ │ ├── Test.js
│ │ │ └── index.js
│ │ │ ├── CheckBoxGroup
│ │ │ ├── README.md
│ │ │ ├── Test.js
│ │ │ └── index.js
│ │ │ ├── Pager
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ │ ├── hoc
│ │ │ └── withDataGroup.js
│ │ │ └── ErrorBound
│ │ │ └── index.js
│ ├── App.js
│ ├── index.js
│ ├── utils
│ │ └── commonTypes.js
│ └── services
│ │ └── student.js
├── public
│ ├── favicon.ico
│ └── index.html
├── .gitignore
├── package.json
└── README.md
├── 旧版生命周期.pptx
├── 新版生命周期 .pptx
└── 属性验证.md
/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | upload
4 | build
5 | ~*
--------------------------------------------------------------------------------
/react-learn/src/components/common/ThreeLayout/README.md:
--------------------------------------------------------------------------------
1 | # 说明文件
2 |
3 |
--------------------------------------------------------------------------------
/旧版生命周期.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/旧版生命周期.pptx
--------------------------------------------------------------------------------
/新版生命周期 .pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/新版生命周期 .pptx
--------------------------------------------------------------------------------
/react-learn/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/public/favicon.ico
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/src/components/common/Banner/img/1.jpg
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/img/2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/src/components/common/Banner/img/2.webp
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/src/components/common/Banner/img/3.jpg
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/src/components/common/Banner/img/4.jpg
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/img/5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DuYi-Edu/DuYi-React/HEAD/react-learn/src/components/common/Banner/img/5.webp
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/index.css:
--------------------------------------------------------------------------------
1 | .banner-container{
2 | position: relative;
3 | border: 2px solid;
4 | overflow: hidden;
5 | }
--------------------------------------------------------------------------------
/react-learn/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function App() {
4 | return (
5 |
6 |
7 | )
8 | }
9 |
--------------------------------------------------------------------------------
/react-learn/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from "./App"
4 |
5 | ReactDOM.render(, document.getElementById('root'));
--------------------------------------------------------------------------------
/react-learn/src/components/common/Modal/index.css:
--------------------------------------------------------------------------------
1 | .modal {
2 | position: fixed;
3 | width: 100%;
4 | height: 100%;
5 | left: 0;
6 | top: 0;
7 | }
8 |
9 | .modal-center {
10 | position: absolute;
11 | left: 50%;
12 | top: 50%;
13 | transform: translate(-50%, -50%);
14 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/ThreeLayout/index.css:
--------------------------------------------------------------------------------
1 | .three-layout {
2 | display: flex;
3 | }
4 |
5 | .three-layout .aside-left {
6 | order: 1;
7 | }
8 |
9 | .three-layout .main{
10 | order: 2;
11 | flex: 1 1 auto;
12 | }
13 |
14 | .three-layout .aside-right{
15 | order: 3;
16 | }
--------------------------------------------------------------------------------
/react-learn/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React App
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/react-learn/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Select/README.md:
--------------------------------------------------------------------------------
1 | **属性**
2 |
3 | 1. datas:一个数组,数组每一项是一个对象,对应一个多选框
4 | 1. 对象具有value和text属性
5 | 2. value:多选框的值
6 | 3. text:多选框的文本
7 |
8 | 例如:
9 |
10 | ```js
11 | datas = [
12 | {value:"football", text:"足球"},
13 | {value:"basketball", text:"篮球"},
14 | {value:"movie", text:"电影"},
15 | ]
16 | ```
17 |
18 | 2. name:每一个多选框的name属性值
19 | 3. value: 当前选中的value值
20 | 4. onChange:当选中项发生改变时的事件
--------------------------------------------------------------------------------
/react-learn/src/components/common/RadioBoxGroup/README.md:
--------------------------------------------------------------------------------
1 | **属性**
2 |
3 | 1. datas:一个数组,数组每一项是一个对象,对应一个多选框
4 | 1. 对象具有value和text属性
5 | 2. value:多选框的值
6 | 3. text:多选框的文本
7 |
8 | 例如:
9 |
10 | ```js
11 | datas = [
12 | {value:"football", text:"足球"},
13 | {value:"basketball", text:"篮球"},
14 | {value:"movie", text:"电影"},
15 | ]
16 | ```
17 |
18 | 2. name:每一个多选框的name属性值
19 | 3. value: 当前选中的value值
20 | 4. onChange:当选中项发生改变时的事件
--------------------------------------------------------------------------------
/react-learn/src/components/common/CheckBoxGroup/README.md:
--------------------------------------------------------------------------------
1 | **属性**
2 |
3 | 1. datas:一个数组,数组每一项是一个对象,对应一个多选框
4 | 1. 对象具有value和text属性
5 | 2. value:多选框的值
6 | 3. text:多选框的文本
7 |
8 | 例如:
9 |
10 | ```js
11 | datas = [
12 | {value:"football", text:"足球"},
13 | {value:"basketball", text:"篮球"},
14 | {value:"movie", text:"电影"},
15 | ]
16 | ```
17 |
18 | 2. name:每一个多选框的name属性值
19 | 3. chooseDatas: 数组,表示当前选中的value值
20 | 4. onChange:当选中项发生改变时的事件
--------------------------------------------------------------------------------
/react-learn/src/components/common/Pager/index.css:
--------------------------------------------------------------------------------
1 | .item {
2 | display: inline-block;
3 | padding: 6px 10px;
4 | border: 1px solid #ccc;
5 | margin: 2px;
6 | color: rgb(23, 96, 121);
7 | cursor: pointer;
8 | }
9 |
10 | .item.disabled{
11 | color: #ccc;
12 | cursor: not-allowed;
13 | }
14 |
15 | .current{
16 | margin-left: 10px;
17 | }
18 |
19 | .active{
20 | border: none;
21 | color: #f40;
22 | cursor: auto;
23 | }
--------------------------------------------------------------------------------
/react-learn/src/utils/commonTypes.js:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types"
2 |
3 | export default {
4 | children: PropTypes.node,
5 | groupDatas: PropTypes.arrayOf(PropTypes.shape({
6 | value: PropTypes.string.isRequired,
7 | text: PropTypes.string.isRequired
8 | })), //多选框组、单选框组、下拉列表的数据源
9 | chooseDatas: PropTypes.arrayOf(PropTypes.string),
10 | singleData: PropTypes.shape({
11 | value: PropTypes.string.isRequired,
12 | text: PropTypes.string.isRequired
13 | })
14 | }
--------------------------------------------------------------------------------
/react-learn/src/services/student.js:
--------------------------------------------------------------------------------
1 | const appkey = "demo13_1545210570249";
2 |
3 | /**
4 | * 获取所有学生
5 | */
6 | export async function getAllStudents() {
7 | return await fetch("/api/student/findAll?appkey=" + appkey)
8 | .then(resp => resp.json()).then(resp => resp.data);
9 | }
10 |
11 | export async function getStudents(page = 1, limit = 10) {
12 | return await fetch(`/api/student/findByPage?appkey=${appkey}&page=${page}&size=${limit}`)
13 | .then(resp => resp.json()).then(resp => resp.data);
14 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/SwitchDot/index.css:
--------------------------------------------------------------------------------
1 | .dots{
2 | position: absolute;
3 | padding: 2px 4px;
4 | background: rgba(255,255,255,.3);
5 | border-radius: 8px;
6 | left: 50%;
7 | bottom: 10px;
8 | transform: translateX(-50%);
9 | display: flex;
10 | }
11 |
12 | .dots span{
13 | width: 8px;
14 | height: 8px;
15 | background: #fff;
16 | border-radius: 50%;
17 | margin: 3px;
18 | cursor: pointer;
19 | }
20 |
21 | .dots span.active{
22 | background: #f40;
23 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/Test.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Banner from "./index"
3 | import src1 from "./img/1.jpg"
4 | import src2 from "./img/2.webp"
5 | import src3 from "./img/3.jpg"
6 | import src4 from "./img/4.jpg"
7 | import src5 from "./img/5.webp"
8 | export default class Test extends Component {
9 | render() {
10 | return (
11 |
12 |
15 |
16 | )
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/hoc/withDataGroup.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import types from "../../../utils/commonTypes"
3 | //实现根据数据渲染出的一组表单组件
4 |
5 | export default function withDataGroup(Comp) {
6 | return class DataGroupWrapper extends React.Component {
7 | static defaultProps = {
8 | datas: []
9 | }
10 |
11 | static propTypes = {
12 | datas: types.groupDatas
13 | }
14 |
15 | render() {
16 | const comps = this.props.datas.map(it => )
17 | return <>
18 | {comps}
19 | >
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/SwitchArrow/index.css:
--------------------------------------------------------------------------------
1 | .arrow{
2 | display: none;
3 | }
4 | .banner-container:hover .arrow{
5 | display: block;
6 | }
7 | .arrow span{
8 | position: absolute;
9 | color: #fff;
10 | width: 20px;
11 | height: 30px;
12 | line-height: 30px;
13 | top: 50%;
14 | transform: translateY(-50%);
15 | background: rgba(0,0,0,.5);
16 | box-sizing: border-box;
17 | cursor: pointer;
18 | }
19 |
20 | .arrow span:hover{
21 | background: rgba(0,0,0,.7);
22 | }
23 |
24 | .arrow .left{
25 | left: 0;
26 | border-radius: 0 30px 30px 0;
27 | }
28 |
29 | .arrow .right{
30 | right: 0;
31 | border-radius: 30px 0 0 30px;
32 | padding-left: 6px;
33 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/ErrorBound/index.js:
--------------------------------------------------------------------------------
1 | import React, { PureComponent } from 'react'
2 |
3 | export default class ErrorBound extends PureComponent {
4 |
5 | state = {
6 | hasError: false
7 | }
8 |
9 | static getDerivedStateFromError(error) {
10 | console.log("发生错误了");
11 | return {
12 | hasError: true
13 | }
14 | }
15 |
16 | componentDidCatch(error, info) {
17 | console.log("记录错误信息");
18 | }
19 |
20 |
21 |
22 | render() {
23 | // setTimeout(() => {
24 | // throw new Error("asfasdfasf");
25 | // }, 1000);
26 | if (this.state.hasError) {
27 | return 出现错误了!
28 | }
29 | return this.props.children
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Modal/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import "./index.css"
3 | import types from "../../../utils/commonTypes"
4 | import PropTypes from "prop-types"
5 |
6 | Modal.defaultProps = { //默认属性
7 | bg: "rgba(0,0,0,.5)"
8 | };
9 |
10 | Modal.propTypes = {
11 | children: types.children,
12 | bg: PropTypes.string,
13 | onClose: PropTypes.func
14 | }
15 |
16 | export default function Modal(props) {
17 |
18 | return (
19 | {
20 | if (e.target.className === "modal") {
21 | props.onClose();
22 | }
23 | }} className="modal" style={{
24 | background: props.bg
25 | }}>
26 |
27 | {props.children}
28 |
29 |
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/SwitchArrow/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import "./index.css";
3 | import PropTypes from "prop-types";
4 | export default class SwitchArrow extends Component {
5 |
6 | static propTypes = {
7 | onChange: PropTypes.func
8 | }
9 |
10 | render() {
11 | return (
12 |
13 | {
14 | this.props.onChange && this.props.onChange("left");
15 | }}>
16 | <
17 |
18 | {
19 | this.props.onChange && this.props.onChange("right");
20 | }}>
21 | >
22 |
23 |
24 | )
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/SwitchDot/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import PropTypes from "prop-types";
3 | import "./index.css"
4 |
5 | export default class SwitchDot extends Component {
6 |
7 | static propTypes = {
8 | total: PropTypes.number.isRequired,
9 | curIndex: PropTypes.number.isRequired, //当前选中的下标
10 | onChange: PropTypes.func
11 | }
12 |
13 | render() {
14 | const spans = [];
15 | for (let i = 0; i < this.props.total; i++) {
16 | spans.push( {
19 | this.props.onChange && this.props.onChange(i)
20 | }}
21 | >);
22 | }
23 | return (
24 |
25 | {spans}
26 |
27 | )
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Select/Test.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Select from "./index"
3 | import { getAllStudents } from "../../../services/student"
4 |
5 | export default class Test extends Component {
6 | state = {
7 | datas: [],
8 | value: ""
9 | }
10 |
11 | async componentDidMount() {
12 | const stus = await getAllStudents();
13 | this.setState({
14 | datas: stus.map(it => ({ value: it.id.toString(), text: it.name }))
15 | })
16 | }
17 |
18 |
19 | render() {
20 | return (
21 |
22 |
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/属性验证.md:
--------------------------------------------------------------------------------
1 | # 属性默认值 和 类型检查
2 |
3 | ## 属性默认值
4 |
5 | 通过一个静态属性```defaultProps```告知react属性默认值
6 |
7 | ## 属性类型检查
8 |
9 | 使用库:```prop-types```
10 |
11 | 对组件使用静态属性```propTypes```告知react如何检查属性
12 |
13 | ```js
14 |
15 | PropTypes.any://任意类型
16 | PropTypes.array://数组类型
17 | PropTypes.bool://布尔类型
18 | PropTypes.func://函数类型
19 | PropTypes.number://数字类型
20 | PropTypes.object://对象类型
21 | PropTypes.string://字符串类型
22 | PropTypes.symbol://符号类型
23 |
24 | PropTypes.node://任何可以被渲染的内容,字符串、数字、React元素
25 | PropTypes.element://react元素
26 | PropTypes.elementType://react元素类型
27 | PropTypes.instanceOf(构造函数)://必须是指定构造函数的实例
28 | PropTypes.oneOf([xxx, xxx])://枚举
29 | PropTypes.oneOfType([xxx, xxx]); //属性类型必须是数组中的其中一个
30 | PropTypes.arrayOf(PropTypes.XXX)://必须是某一类型组成的数组
31 | PropTypes.objectOf(PropTypes.XXX)://对象由某一类型的值组成
32 | PropTypes.shape(对象): //属性必须是对象,并且满足指定的对象要求
33 | PropTypes.exact({...})://对象必须精确匹配传递的数据
34 |
35 | //自定义属性检查,如果有错误,返回错误对象即可
36 | 属性: function(props, propName, componentName) {
37 | //...
38 | }
39 | ```
--------------------------------------------------------------------------------
/react-learn/src/components/common/RadioBoxGroup/Test.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import RadioBoxGroup from "./index"
3 | import { getAllStudents } from "../../../services/student"
4 |
5 | export default class Test extends Component {
6 | state = {
7 | datas: [],
8 | value: ""
9 | }
10 |
11 | async componentDidMount() {
12 | const stus = await getAllStudents();
13 | this.setState({
14 | datas: stus.map(it => ({ value: it.id.toString(), text: it.name }))
15 | })
16 | }
17 |
18 |
19 | render() {
20 | return (
21 |
22 | {
26 | this.setState({
27 | value: val
28 | })
29 | }}
30 | />
31 |
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/CheckBoxGroup/Test.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import CheckBoxGroup from "./index"
3 | import { getAllStudents } from "../../../services/student"
4 |
5 | export default class Test extends Component {
6 | state = {
7 | datas: [],
8 | chooseDatas: []
9 | }
10 |
11 | async componentDidMount() {
12 |
13 | const stus = await getAllStudents();
14 | this.setState({
15 | datas: stus.map(it => ({ value: it.id.toString(), text: it.name }))
16 | })
17 | }
18 |
19 |
20 | render() {
21 | return (
22 |
23 | {
27 | this.setState({
28 | chooseDatas: newArr
29 | })
30 | }}
31 | />
32 |
33 | )
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/react-learn/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-learn",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "animate.css": "^3.7.2",
7 | "query-string": "^6.8.2",
8 | "react": "^16.8.6",
9 | "react-dom": "^16.8.6",
10 | "react-router-dom": "^5.0.1",
11 | "react-scripts": "3.0.1",
12 | "react-transition-group": "^4.2.2",
13 | "uuid": "^3.3.2"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": "react-app"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | },
36 | "proxy": "http://api.duyiedu.com",
37 | "devDependencies": {
38 | "typescript": "^3.5.3"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/RadioBoxGroup/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import types from "../../../utils/commonTypes"
3 | import PropTypes from "prop-types"
4 | import withDataGroup from "../hoc/withDataGroup";
5 |
6 | class Radio extends Component {
7 | static propTypes = {
8 | name: PropTypes.string.isRequired,
9 | info: types.singleData.isRequired, //当前单选框的value
10 | value: PropTypes.string.isRequired, //当前选中的value值
11 | onChange: PropTypes.func
12 | }
13 |
14 | render() {
15 | return
27 | }
28 | }
29 |
30 | export default withDataGroup(Radio);
31 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Select/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import types from "../../../utils/commonTypes"
3 | import PropTypes from "prop-types"
4 | import withDataGroup from "../hoc/withDataGroup";
5 |
6 | class Option extends Component {
7 | static propTypes = {
8 | info: types.singleData
9 | }
10 |
11 | render() {
12 | return
15 | }
16 | }
17 |
18 | const OptGroup = withDataGroup(Option);
19 |
20 | export default class Select extends Component {
21 | static propTypes = {
22 | name: PropTypes.string.isRequired,
23 | value: PropTypes.string.isRequired,
24 | onChange: PropTypes.func
25 | }
26 |
27 |
28 | render() {
29 | return
36 | }
37 | }
--------------------------------------------------------------------------------
/react-learn/src/components/common/ThreeLayout/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import "./index.css"
3 | import types from "../../../utils/commonTypes"
4 | import PropTypes from "prop-types"
5 |
6 | ThreeLayout.defaultProps = {
7 | leftWidth: 200,
8 | rightWidth: 200,
9 | minWidth: 800,
10 | gap: 0//间隙
11 | };
12 |
13 | ThreeLayout.propTypes = {
14 | leftWidth: PropTypes.number,
15 | rightWidth: PropTypes.number,
16 | minWidth: PropTypes.number,
17 | gap: PropTypes.number,
18 | children: types.children,
19 | left: PropTypes.node,
20 | right: PropTypes.node
21 | }
22 |
23 | export default function ThreeLayout(props) {
24 | return (
25 |
28 |
29 | {props.children}
30 |
31 |
35 | {props.left}
36 |
37 |
41 | {props.right}
42 |
43 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/CheckBoxGroup/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import types from "../../../utils/commonTypes"
3 | import PropTypes from "prop-types"
4 | import withDataGroup from "../hoc/withDataGroup"
5 | class CheckBox extends Component {
6 | static propTypes = {
7 | name: PropTypes.string.isRequired,
8 | onChange: PropTypes.func,
9 | info: types.singleData.isRequired,
10 | chooseDatas: types.chooseDatas.isRequired
11 | }
12 |
13 | handleChange = e => {
14 | let newArr;
15 | if (e.target.checked) {
16 | newArr = [...this.props.chooseDatas, e.target.value];
17 | }
18 | else {
19 | newArr = this.props.chooseDatas.filter(it => it !== e.target.value);
20 | }
21 | this.props.onChange && this.props.onChange(newArr);
22 | }
23 |
24 | render() {
25 | return ();
35 | }
36 | }
37 |
38 | /**
39 | * 一组多选框
40 | */
41 | export default withDataGroup(CheckBox);
42 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/ImgContainer/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import PropTypes from "prop-types"
3 |
4 | export default class ImgContainer extends Component {
5 |
6 | static propTypes = {
7 | imgSrcs: PropTypes.arrayOf(PropTypes.string).isRequired, //图片路径的数组
8 | imgWidth: PropTypes.number.isRequired, //单张图片宽度
9 | imgHeight: PropTypes.number.isRequired, //单张图片高度
10 | duration: PropTypes.number.isRequired, //在多长时间内完成动画切换
11 | }
12 |
13 | containerRef = el => {
14 | this.div = el;
15 | }
16 |
17 | //计时器的间隔时间
18 | tick = 16
19 |
20 | timer = null;//计时器序号
21 |
22 | /**
23 | * 切换到第几张图片
24 | * 调用该函数,此组件会经过一段动画完成切换
25 | * @param {*} index 图片下标,从0开始
26 | */
27 | switchTo(index) {
28 | //设置正确的index
29 | if (index < 0) {
30 | index = 0;
31 | }
32 | else if (index > this.props.imgSrcs.length - 1) {
33 | index = this.props.imgSrcs.length - 1;
34 | }
35 | //1. 根据index,计算div的最终的marginLeft
36 | const targetLeft = -index * this.props.imgWidth;
37 | //2. 得到当前的marginLeft
38 | let curLeft = parseFloat(window.getComputedStyle(this.div).marginLeft);
39 | //3. 计算运动的次数
40 | const times = Math.ceil(this.props.duration / this.tick);
41 | let curTimes = 0; //当前运动的次数
42 | //4. 计算每次运动的距离
43 | const totalDis = targetLeft - curLeft; //总距离
44 | const dis = totalDis / times; //每次运动的距离
45 | //先停止之前的动画
46 | clearInterval(this.timer);
47 | this.timer = setInterval(() => {
48 | curTimes++;
49 | curLeft += dis;
50 | this.div.style.marginLeft = curLeft + "px";
51 | if (curTimes === times) {
52 | //停止运动
53 | this.div.style.marginLeft = targetLeft + "px";
54 | clearInterval(this.timer);
55 | }
56 | }, this.tick)
57 | }
58 |
59 | render() {
60 | const imgs = this.props.imgSrcs.map((src, i) =>
)
65 | return (
66 |
72 | {imgs}
73 |
74 | )
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Pager/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import "./index.css"
3 |
4 | /**
5 | * 分页组件
6 | * 属性:
7 | * 1. current:初始页码
8 | * 2. total:总数据量
9 | * 3. limit:页容量,每页显示的数据量
10 | * 4. panelNumber:数字页码最多显示多少个
11 | * 5. onPageChange:当页码改变的事件
12 | */
13 | export default function Pager(props) {
14 | const pageNumber = getPageNumber(props); //总页数
15 | if (pageNumber === 0) {
16 | return null;
17 | }
18 | const min = getMinNumber(props);//最小数字
19 | const max = getMaxNumber(min, pageNumber, props); //最大数字
20 | const numbers = [];
21 | for (let i = min; i <= max; i++) {
22 | numbers.push( { toPage(i, props) }} className={i === props.current ? "item active" : "item"}>{i})
23 | }
24 | return (
25 | <>
26 | { toPage(1, props) }}
28 | className={props.current === 1 ? "item disabled" : "item"}
29 | >首页
30 | { toPage(props.current - 1 < 1 ? 1 : props.current - 1, props) }}
32 | className={props.current === 1 ? "item disabled" : "item"}
33 | >上一页
34 | {/* 数字页码 */}
35 | {numbers}
36 | { toPage(props.current + 1 > pageNumber ? pageNumber : props.current + 1, props) }}
38 | className={props.current === pageNumber ? "item disabled" : "item"}
39 | >下一页
40 | { toPage(pageNumber, props) }}
42 | className={props.current === pageNumber ? "item disabled" : "item"}
43 | >尾页
44 |
45 | {props.current}
46 | /
47 | {pageNumber}
48 | >
49 | );
50 | }
51 |
52 | /**
53 | * 计算最小数字
54 | */
55 | function getMinNumber(props) {
56 | var min = props.current - Math.floor(props.panelNumber / 2)
57 | if (min < 1) {
58 | min = 1;
59 | }
60 | return min;
61 | }
62 |
63 | /**
64 | * 计算最大数字
65 | * @param {*} min
66 | * @param {*} pageNumber
67 | */
68 | function getMaxNumber(min, pageNumber, props) {
69 | var max = min + props.panelNumber - 1;
70 | if (max > pageNumber) {
71 | max = pageNumber;
72 | }
73 | return max;
74 | }
75 |
76 | /**
77 | * 跳转到某一页
78 | * @param {*} target 目标页码
79 | * @param {*} props 所有属性
80 | */
81 | function toPage(target, props) {
82 | if (props.current === target) {
83 | return; //目标页码和当前页码相同
84 | }
85 | props.onPageChange && props.onPageChange(target);
86 | }
87 |
88 |
89 | /**
90 | * 计算总页数
91 | * @param {*} props
92 | */
93 | function getPageNumber(props) {
94 | return Math.ceil(props.total / props.limit);
95 | }
--------------------------------------------------------------------------------
/react-learn/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `npm start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `npm test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `npm run build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `npm run eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `npm run build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/react-learn/src/components/common/Banner/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import "./index.css"
3 | import PropTypes from "prop-types";
4 | import ImgContainer from "./ImgContainer"
5 | import SwitchArrow from "./SwitchArrow"
6 | import SwitchDot from './SwitchDot'
7 |
8 | export default class Banner extends Component {
9 |
10 | static defaultProps = {
11 | width: 520,
12 | height: 280,
13 | imgSrcs: [],
14 | autoDuration: 3000,
15 | duration: 500
16 | }
17 |
18 | static propTypes = {
19 | width: PropTypes.number.isRequired,//容器宽度
20 | height: PropTypes.number.isRequired, //容器高度
21 | imgSrcs: PropTypes.arrayOf(PropTypes.string).isRequired, //图片路径数组
22 | autoDuration: PropTypes.number.isRequired, //自动切换的间隔时间
23 | duration: PropTypes.number.isRequired,//完成一次切换需要的时间
24 | }
25 |
26 | timer = null; //自动切换的计时器
27 |
28 | autoSwitch() {
29 | clearInterval(this.timer);
30 | this.timer = setInterval(() => {
31 | var cur = this.state.curIndex;
32 | cur = (cur + 1) % this.props.imgSrcs.length;
33 | this.handleSwitch(cur);
34 | }, this.props.autoDuration)
35 | }
36 |
37 | componentWillUnmount() {
38 | clearInterval(this.timer);
39 | }
40 |
41 |
42 | componentDidMount() {
43 | this.autoSwitch();
44 | }
45 |
46 |
47 | state = {
48 | curIndex: 0 //当前显示的第几张图片
49 | }
50 |
51 | imgContainerRef = el => {
52 | this.imgContainer = el;
53 | }
54 |
55 | handleArrowChange = type => {
56 | var cur = this.state.curIndex;
57 | if (type === "left") {
58 | cur--;
59 | if (cur < 0) {
60 | cur = this.props.imgSrcs.length - 1;
61 | }
62 | }
63 | else {
64 | cur++;
65 | if (cur > this.props.imgSrcs.length - 1) {
66 | cur = 0;
67 | }
68 | }
69 | this.handleSwitch(cur);
70 | }
71 |
72 | /**
73 | * 切换到
74 | */
75 | handleSwitch = index => {
76 | this.setState({
77 | curIndex: index
78 | })
79 | //得到ImgContainer的组件对象
80 | this.imgContainer.switchTo(index);
81 | }
82 |
83 | render() {
84 | return (
85 | {
92 | clearInterval(this.timer);
93 | }}
94 | onMouseLeave={()=>{
95 | this.autoSwitch();
96 | }}
97 | >
98 |
105 |
108 |
113 |
114 | )
115 | }
116 | }
117 |
--------------------------------------------------------------------------------