├── 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 |
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 |
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 |
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: '实习'}];
--------------------------------------------------------------------------------