node.js+react全栈实践
利用业余时间写了个简单的项目,使用react+node.js做的一个全栈实践项目,前端参考了[React-Admin-Starter](https://github.com/veryStarters/react-admin-starter)这个项目,这个项目的自动配置路由,自动页面骨架的思路很新颖。后端是node.js+express提供接口访问,最主要的内容是mysql.js的使用和使用nginx反向代理来跨域。
1.前端parttime
前端基于框架React-Admin-Starter基本没有改动。这是一个后台管理系统,最常用的功能也就是增删改查,这里做了一些自己的调整。
1.1.统一的字段名
开发PC端这种后台项目,产品经理经常会提一些临时需求。比如原型上一个表格字段“编辑时间”,做到一般快结尾了或者已经快上线了,说要改成“更新时间”。这个时候就比较蛋疼了,当然最直接的办法就是Ctrl+H全局查找,一个一个替换,但是遇到新手连编辑器都不是很熟的小伙伴就要捉急了(我见过一些刚入门的小伙子,用的是vscode,还真不知道全局查找,快速跳转这些快捷键)。
前端项目中使用的是ant.design for react,table有两个地方需要注意,数据源和显示列名:
// 数据源const dataSource = [ { key: '1', name: '胡彦斌', age: 32, address: '西湖区湖底公园1号' }, { key: '2', name: '胡彦祖', age: 42, address: '西湖区湖底公园1号' } ]; // 显示列const columns = [ { title: '姓名', dataIndex: 'name', key: 'name' }, { title: '年龄', dataIndex: 'age', key: 'age' }, { title: '住址', dataIndex: 'address', key: 'address' } ]
这里可以把所有字段单独写在一个文件里面,从同一个地方引用这个字段,这样只修改这一个字段所有的名字都改过来了。如下,columns.js 定义字段:
const id = { title: 'ID', dataIndex: 'id', key: 'id', type: 'input' } const name = { title: '姓名', dataIndex: 'name', key: 'name', type: 'input' } const mobile = { title: '手机号', dataIndex: 'mobile', key: 'mobile', type: 'input' } const email = { title: '邮箱', dataIndex: 'email', key: 'email', type: 'input' } const thumb = { title: '头像', dataIndex: 'thumb', key: 'thumb', render: src => <img alt='' src={ src }/> }const user = [id, name, email, mobile, thumb, createTime, updateTime] export { user }
user/list/index.js使用字段:
import { user } from './../../../columns'<Table dataSource={userList} pagination={paginationProps} columns={user})} rowKey='id' size="middle" bordered/>
问题来了,如果有编辑,删除字段怎么办呢?这个时候就需要和引用它的地方交互了。这里可以使用给子组件传递函数的方法来实现:
const action = props => { let { handleDelete, handleEdit } = props return { title: '操作', key: 'action', render: (text, record) => <span> <Popconfirm title='确定删除?' onConfirm={() => handleDelete(record)} okText="确定" cancelText="取消"> <Icon type="delete" className={style.deleteLink}/> </Popconfirm> <Divider type="vertical"/> <Icon type="edit" onClick={() => handleEdit(record)}/> </span> } } const user = { column: props => [id, name, email, mobile, thumb, createTime, updateTime, action(props)] }
在使用这个字段的时候就可以调用一个函数:
handleDelete(record) { api.user.deleteUser({ id: record.id }).then(res => { if (res.success) { this.search() } }) } <Table dataSource={userList} pagination={paginationProps} columns={user.column({ handleDelete: this.handleDelete.bind(this), handleEdit: this.handleEdit.bind(this) })} rowKey='id' size="middle" bordered/>
这里给Table的columns属性赋的是一个函数,函数参数是一个也是一个函数,这样子组件就可以调用到这个函数,有点拗口,你懂就好。columns.js中的action字段只是一个桥梁作用,根据具体逻辑传递进去的函数执行不同的操作,不同场合执行的操作不同,但是操作是类似的,基本都是删除,和编辑两个逻辑。
分页也有类似的问题,比如那天产品经理说:“分页样式统一起来,每个地方可选的每页个数都是20, 30, 50, 100”。我们也可以把这个定义在同一个地方,方便修改。这里仍然定义在columns.js中