├── index.html ├── README.md ├── package.json ├── webpack.config.js └── src ├── StaffItem.js ├── StaffItemPanel.js ├── StaffHeader.js ├── ManageSystem.js ├── StaffFooter.js ├── StaffDetail.js └── STAFF.js /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 实验室人员管理 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 1.使用方法 2 | 3 | ### 1.1安装依赖项 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | ### 1.2生成bundle.js 10 | 11 | ``` 12 | npm start 13 | ``` 14 | 15 | ### 1.3在浏览器运行index.html即可 16 | 17 | 源代码中包含生成好的bundle.js,可以直接点击运行。 18 | 19 | # 2.相关资料 20 | 21 | 在线预览:[人员管理](http://wyuhao.com/demo/staff) 22 | 23 | 代码解析:[十分详细的React实例](http://blog.csdn.net/a153375250/article/details/52667739) 24 | 25 | # 3.致谢 26 | 27 | 如果对你有帮助,就奉献一颗Star吧! 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "StaffManage", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "", 6 | "scripts": { 7 | "start": "webpack" 8 | }, 9 | "author": "WYH", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-core": "^6.14.0", 13 | "babel-loader": "^6.2.5", 14 | "babel-preset-es2015": "^6.14.0", 15 | "babel-preset-react": "^6.11.1", 16 | "webpack": "^1.13.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: __dirname + '/src/ManageSystem.js', 3 | output: { 4 | path: __dirname + '/build', 5 | filename: "bundle.js" 6 | }, 7 | externals: { 8 | 'react': 'React' 9 | }, 10 | devtool: 'eval-source-map', //生成source file 11 | module: { 12 | loaders: [ 13 | { 14 | test: /\.js$/, 15 | exclude: /node_modules/, 16 | loader: 'babel', 17 | query: { 18 | presets: ['es2015', 'react'] 19 | } 20 | } 21 | ] 22 | } 23 | }; -------------------------------------------------------------------------------- /src/StaffItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export default class StaffItem extends React.Component{ 3 | 4 | //delete 5 | handlerDelete(evt){ 6 | this.props.removeStaffItem(this.props.item.key); 7 | } 8 | 9 | //detail 10 | handlerDetail(evt){ 11 | this.props.detailStaffItem(this.props.item.key); 12 | } 13 | 14 | render(){ 15 | return ( 16 | 19 | {this.props.item.info.name} 20 | {this.props.item.info.age} 21 | {this.props.item.info.id} 22 | {this.props.item.info.sex} 23 | 24 | 删除 25 | 详情 26 | 27 | 28 | ); 29 | } 30 | } -------------------------------------------------------------------------------- /src/StaffItemPanel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import StaffItem from './StaffItem.js'; 3 | export default class StaffItemPanel extends React.Component{ 4 | 5 | render(){ 6 | let items = []; 7 | 8 | if(this.props.items.length == 0) { 9 | items.push(暂无用户); 10 | }else { 11 | this.props.items.forEach(item => { 12 | items.push(); 13 | }); 14 | } 15 | 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | {items} 26 |
姓名年龄身份性别操作
27 | ); 28 | } 29 | } -------------------------------------------------------------------------------- /src/StaffHeader.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export default class StaffHeader extends React.Component{ 3 | 4 | //排序 5 | handlerOrderChange(){ 6 | let sel = React.findDOMNode(this.refs.selOrder); 7 | let selValue = sel.options[sel.selectedIndex].value; 8 | this.props.sortStaff(selValue); 9 | } 10 | 11 | //筛选 12 | handlerIdChange(){ 13 | let sel = React.findDOMNode(this.refs.selId); 14 | let selValue = sel.options[sel.selectedIndex].value; 15 | this.props.filtStaff(selValue); 16 | } 17 | 18 | //search 19 | handlerSearch(){ 20 | let bar = React.findDOMNode(this.refs.searchBar); 21 | let value = bar.value; 22 | this.props.searchStaff(value); 23 | } 24 | 25 | render(){ 26 | return ( 27 |
28 |

人员管理系统

29 | 30 | 31 | 32 | 33 | 43 | 51 | 52 | 53 |
34 | 35 | 42 | 44 | 45 | 50 |
54 |
55 | ); 56 | } 57 | } -------------------------------------------------------------------------------- /src/ManageSystem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import StaffHeader from './StaffHeader.js'; 3 | import StaffItemPanel from './StaffItemPanel.js'; 4 | import StaffFooter from './StaffFooter.js'; 5 | import StaffDetail from './StaffDetail.js'; 6 | 7 | import Staff from './STAFF.js'; 8 | 9 | 10 | class App extends React.Component { 11 | constructor(){ 12 | super(); 13 | this.state = { 14 | staff : new Staff, 15 | staffDetail: null 16 | }; 17 | } 18 | 19 | //增 20 | addStaffItem(item){ 21 | this.setState({ 22 | staff: this.state.staff.addStaffItem(item) 23 | }); 24 | } 25 | //删 26 | removeStaffItem(key){ 27 | this.setState({ 28 | staff: this.state.staff.removeStaffItem(key) 29 | }); 30 | } 31 | 32 | /* 33 | *详情 34 | */ 35 | //打开 36 | detailStaffItem(key){ 37 | this.setState({ 38 | staffDetail: this.state.staff.staff.filter(item => { 39 | return item.key==key; 40 | })[0] 41 | }); 42 | } 43 | //关闭 44 | closeDetail(){ 45 | this.setState({ 46 | staffDetail: null 47 | }); 48 | } 49 | //编辑 50 | editDetail(item){ 51 | this.setState({ 52 | staff : this.state.staff.editStaffItem(item) 53 | }); 54 | } 55 | 56 | /* 57 | * 排序 58 | */ 59 | sortStaff(sortType) { 60 | this.setState({ 61 | staff: this.state.staff.sortStaff(sortType) 62 | }); 63 | } 64 | 65 | /* 66 | * 筛选 67 | */ 68 | filtStaff(filtType) { 69 | this.setState({ 70 | staff: this.state.staff.filtStaff(filtType) 71 | }); 72 | } 73 | 74 | /* 75 | * 搜索 76 | */ 77 | searchStaff(word) { 78 | this.setState({ 79 | staff: this.state.staff.searchStaff(word) 80 | }); 81 | } 82 | 83 | 84 | render(){ 85 | return ( 86 |
87 | 88 | 89 | 90 | 91 |
92 | ); 93 | } 94 | } 95 | 96 | React.render(, document.getElementById('app')); -------------------------------------------------------------------------------- /src/StaffFooter.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export default class StaffFooter extends React.Component{ 3 | 4 | handlerAddClick(evt){ 5 | evt.preventDefault(); 6 | let item = {}; 7 | let addForm = React.findDOMNode(this.refs.addForm); 8 | let sex = addForm.querySelector('#staffAddSex'); 9 | let id = addForm.querySelector('#staffAddId'); 10 | 11 | item.name = addForm.querySelector('#staffAddName').value.trim(); 12 | item.age = addForm.querySelector('#staffAddAge').value.trim(); 13 | item.descrip = addForm.querySelector('#staffAddDescrip').value.trim(); 14 | item.sex = sex.options[sex.selectedIndex].value; 15 | item.id = id.options[id.selectedIndex].value; 16 | 17 | /* 18 | *表单验证 19 | */ 20 | if(item.name=='' || item.age=='' || item.descrip=='') { 21 | let tips = React.findDOMNode(this.refs.tipsUnDone); 22 | tips.style.display = 'block'; 23 | setTimeout(function(){ 24 | tips.style.display = 'none'; 25 | }, 1000); 26 | return; 27 | } 28 | //非负整数 29 | let numReg = /^\d+$/; 30 | if(!numReg.test(item.age) || parseInt(item.age)>150) { 31 | let tips = React.findDOMNode(this.refs.tipsUnAge); 32 | tips.style.display = 'block'; 33 | setTimeout(function(){ 34 | tips.style.display = 'none'; 35 | }, 1000); 36 | return; 37 | } 38 | 39 | this.props.addStaffItem(item); 40 | addForm.reset(); 41 | 42 | //此处应在返回添加成功信息后确认 43 | let tips = React.findDOMNode(this.refs.tips); 44 | tips.style.display = 'block'; 45 | setTimeout(function(){ 46 | tips.style.display = 'none'; 47 | }, 1000); 48 | } 49 | 50 | render(){ 51 | return ( 52 |
53 |

人员新增

54 |
55 |
56 |
57 | 58 | 59 |
60 |
61 | 62 | 63 |
64 |
65 | 66 | 70 |
71 |
72 | 73 | 79 |
80 |
81 | 82 | 83 |
84 |

提交成功

85 |

请录入完整的人员信息

86 |

请录入正确的年龄

87 |
88 | 89 |
90 |
91 |
92 | ) 93 | } 94 | } -------------------------------------------------------------------------------- /src/StaffDetail.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | export default class StaffDetail extends React.Component{ 3 | 4 | handlerEdit(){ 5 | let item = {}; 6 | let editTabel = React.findDOMNode(this.refs.editTabel); 7 | let sex = editTabel.querySelector('#staffEditSex'); 8 | let id = editTabel.querySelector('#staffEditId'); 9 | 10 | item.name = editTabel.querySelector('#staffEditName').value.trim(); 11 | item.age = editTabel.querySelector('#staffEditAge').value.trim(); 12 | item.descrip = editTabel.querySelector('#staffEditDescrip').value.trim(); 13 | item.sex = sex.options[sex.selectedIndex].value; 14 | item.id = id.options[id.selectedIndex].value; 15 | item.key = this.props.staffDetail.key; 16 | 17 | /* 18 | *表单验证 19 | */ 20 | if(item.name=='' || item.age=='' || item.descrip=='') { 21 | let tips = React.findDOMNode(this.refs.DtipsUnDone); 22 | tips.style.display = 'block'; 23 | setTimeout(function(){ 24 | tips.style.display = 'none'; 25 | }, 1000); 26 | return; 27 | } 28 | //非负整数 29 | let numReg = /^\d+$/; 30 | if(!numReg.test(item.age) || parseInt(item.age)>150) { 31 | let tips = React.findDOMNode(this.refs.DtipsUnAge); 32 | tips.style.display = 'block'; 33 | setTimeout(function(){ 34 | tips.style.display = 'none'; 35 | }, 1000); 36 | return; 37 | } 38 | 39 | this.props.editDetail(item); 40 | 41 | //此处应在返回修改成功信息后确认 42 | let tips = React.findDOMNode(this.refs.Dtips); 43 | tips.style.display = 'block'; 44 | setTimeout(function(){ 45 | tips.style.display = 'none'; 46 | }, 1000); 47 | } 48 | 49 | handlerClose(){ 50 | this.props.closeDetail(); 51 | } 52 | 53 | componentDidUpdate(){ 54 | if(this.props.staffDetail == null){} 55 | else { 56 | let selSex = React.findDOMNode(this.refs.selSex); 57 | for(let i=0; i 81 |

点击'完成'保存修改,点击'关闭'放弃未保存修改并退出.

82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 101 | 102 | 103 | 104 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
姓名
年龄
性别 96 | 100 |
身份 105 | 111 |
个人描述
119 |

修改成功

120 |

请录入完整的人员信息

121 |

请录入正确的年龄

122 | 123 | 124 | 125 | ); 126 | } 127 | } -------------------------------------------------------------------------------- /src/STAFF.js: -------------------------------------------------------------------------------- 1 | class staffItem { 2 | constructor(item){ 3 | this.info = {}; 4 | this.info.name = item.name; 5 | this.info.age = item.age || 0; 6 | this.info.sex = item.sex; 7 | this.info.id = item.id; 8 | this.info.descrip = item.descrip || ''; 9 | this.key = ++staffItem.key; 10 | } 11 | } 12 | staffItem.key = 0; 13 | 14 | export default class STAFF { 15 | 16 | constructor(){ 17 | this.allStaff = [ 18 | new staffItem(STAFF.rawData[0]), 19 | new staffItem(STAFF.rawData[1]), 20 | new staffItem(STAFF.rawData[2]), 21 | new staffItem(STAFF.rawData[3]), 22 | new staffItem(STAFF.rawData[4]), 23 | new staffItem(STAFF.rawData[5]), 24 | new staffItem(STAFF.rawData[6]), 25 | new staffItem(STAFF.rawData[7]), 26 | new staffItem(STAFF.rawData[8]), 27 | new staffItem(STAFF.rawData[9]), 28 | new staffItem(STAFF.rawData[10]) 29 | ]; 30 | this.staff = []; 31 | this.sortType = 0;//0-身份 1-年龄升 2-年龄降 32 | this.filtType = 0;//0-all 1-主任 2-老师 3-学生 4-实习 33 | this.word = '';//搜索关键字 34 | this._sortStaff(this.sortType); //默认按身份排序 35 | this._filtStaff(this.filtType); 36 | } 37 | 38 | //增 39 | addStaffItem(item) { 40 | let newItem = new staffItem(item); 41 | this.allStaff.push(newItem); 42 | //排序 筛选 搜索过滤 43 | this._sortStaff(this.sortType); 44 | this._filtStaff(this.filtType); 45 | this._searchStaff(this.word); 46 | return this; 47 | } 48 | 49 | //删 50 | removeStaffItem(key) { 51 | let newStaff = this.allStaff.filter(item => { 52 | return item.key != key; 53 | }); 54 | this.allStaff = newStaff; 55 | //筛选 搜多过滤 56 | this._filtStaff(this.filtType); 57 | this._searchStaff(this.word); 58 | return this; 59 | } 60 | 61 | //改 62 | editStaffItem(item) { 63 | this.allStaff.forEach(staffItem => { 64 | if(staffItem.key == item.key) { 65 | staffItem.info.name = item.name; 66 | staffItem.info.sex = item.sex; 67 | staffItem.info.age = item.age; 68 | staffItem.info.id = item.id; 69 | staffItem.info.descrip = item.descrip; 70 | } 71 | }); 72 | this._sortStaff(this.sortType); 73 | this._filtStaff(this.filtType); 74 | this._searchStaff(this.word); 75 | return this; 76 | } 77 | 78 | //筛选 79 | _filtStaff(filtType){ 80 | this.filtType = filtType; 81 | switch(parseInt(filtType)){ 82 | case 0: 83 | this.staff = this.allStaff; 84 | break; 85 | case 1: 86 | this.staff = this.allStaff.filter(item => { 87 | return item.info.id == '主任'; 88 | }); 89 | break; 90 | case 2: 91 | this.staff = this.allStaff.filter(item => { 92 | return item.info.id == '老师'; 93 | }); 94 | break; 95 | case 3: 96 | this.staff = this.allStaff.filter(item => { 97 | return item.info.id == '学生'; 98 | }); 99 | break; 100 | case 4: 101 | this.staff = this.allStaff.filter(item => { 102 | return item.info.id == '实习'; 103 | }); 104 | break; 105 | default: break; 106 | } 107 | } 108 | 109 | //排序 110 | _sortStaff(sortType) { 111 | this.sortType = sortType; 112 | switch(parseInt(sortType)){ 113 | case 0: //身份 114 | this.allStaff.forEach(item => { 115 | switch(item.info.id) { 116 | case '主任': 117 | item.info.id = 1; break; 118 | case '老师': 119 | item.info.id = 2; break; 120 | case '学生': 121 | item.info.id = 3; break; 122 | case '实习': 123 | item.info.id = 4; break; 124 | default: break; 125 | } 126 | }); 127 | this.allStaff.sort(function(item1, item2){ 128 | if(item1.info.id < item2.info.id) 129 | return -1; 130 | else if (item1.info.id > item2.info.id) 131 | return 1; 132 | else 133 | return 0; 134 | }); 135 | this.allStaff.forEach(item => { 136 | switch(item.info.id) { 137 | case 1: 138 | item.info.id = '主任'; break; 139 | case 2: 140 | item.info.id = '老师'; break; 141 | case 3: 142 | item.info.id = '学生'; break; 143 | case 4: 144 | item.info.id = '实习'; break; 145 | default: break; 146 | } 147 | }); 148 | break; 149 | case 1: //年龄升 150 | this.allStaff.sort(function(item1, item2){ 151 | if(item1.info.age < item2.info.age) 152 | return -1; 153 | else if (item1.info.age > item2.info.age) 154 | return 1; 155 | else 156 | return 0; 157 | }); 158 | break; 159 | case 2: //年龄降 160 | this.allStaff.sort(function(item1, item2){ 161 | if(item1.info.age < item2.info.age) 162 | return 1; 163 | else if (item1.info.age > item2.info.age) 164 | return -1; 165 | else 166 | return 0; 167 | }); 168 | break; 169 | default: break; 170 | } 171 | } 172 | 173 | //搜索 174 | _searchStaff(word){ 175 | this.word = word; 176 | //在staff中搜索 177 | this.staff = this.staff.filter(item => { 178 | return item.info.name.indexOf(word)!=-1 || 179 | (item.info.age+'').indexOf(word)!=-1 || 180 | item.info.id.indexOf(word)!=-1 || 181 | item.info.sex.indexOf(word)!=-1; 182 | }); 183 | } 184 | 185 | filtStaff(filtType){ 186 | this._filtStaff(filtType); 187 | this._searchStaff(this.word); 188 | return this; 189 | } 190 | sortStaff(sortType){ 191 | this._sortStaff(sortType); 192 | this._filtStaff(this.filtType); 193 | this._searchStaff(this.word); 194 | return this; 195 | } 196 | searchStaff(word){ 197 | this._filtStaff(this.filtType); 198 | this._searchStaff(word); 199 | return this; 200 | } 201 | } 202 | //模拟数据库 203 | STAFF.rawData = [{ descrip:'我是一匹来自远方的狼。', sex: '男', age: 20, name: '张三', id: '主任'}, 204 | { descrip:'我是一匹来自远方的狼。', sex: '女', age: 21, name: '赵静', id: '学生'}, 205 | { descrip:'我是一匹来自远方的狼。', sex: '女', age: 22, name: '王二麻', id: '学生'}, 206 | { descrip:'我是一匹来自远方的狼。', sex: '女', age: 24, name: '李晓婷', id: '实习'}, 207 | { descrip:'我是一匹来自远方的狼。', sex: '男', age: 23, name: '张春田', id: '实习'}, 208 | { descrip:'我是一匹来自远方的狼。', sex: '男', age: 22, name: '刘建国', id: '学生'}, 209 | { descrip:'我是一匹来自远方的狼。', sex: '男', age: 24, name: '张八', id: '主任'}, 210 | { descrip:'我是一匹来自远方的狗。', sex: '男', age: 35, name: '李四', id: '老师'}, 211 | { descrip:'我是一匹来自远方的猪。', sex: '男', age: 42, name: '王五', id: '学生'}, 212 | { descrip:'我是一匹来自远方的牛。', sex: '男', age: 50, name: '赵六', id: '实习'}, 213 | { descrip:'我是一匹来自远方的马。', sex: '男', age: 60, name: '孙七', id: '实习'}]; --------------------------------------------------------------------------------