最近几个月一直在做自己的毕业设计,仿照猫眼完成一整套的电影订票系统,整个系统由React网页端、ReactNative的手机端、Node的服务端和管理系统组成。虽然是完成了,但是因为自己还在忙着实习的工作,所以有些地方做得很粗糙。这几天空闲下来打算把自己的代码整理一下,梳理一下知识结构同时也想和更多人交流技术。
组件分析
猫眼官网上的电影选座组件截图如下:
原图
为了讲解的方便,我对图中的一些部分进行了标号。具体分析如下:
一.、座位分析
从“1”中可以看到,整个组件中有4种类型的座位,分别是可选、已售、已选、情侣座位,所有类型的座位都会在“5”的座位显示区域出现。这个时候就需要思考怎么去保存座位的信息,其中有几点需要注意:
1、如何表示座位。每个影厅的座位数不一样,座椅的行数和列数都不相同。甚至为了表示方便,会出现“座位空隙”,举个例子在某个影厅里面有一排楼梯,这个楼梯的位置就要从影厅的布局上给预留出来。
2、如何表示座位的状态。一个座位从图中可以看到有“可选”、"已售"、“已选”的状态(说明:本次不考虑情侣座的情况),需要采用一个恰当的方式,去保存座位的状态。
二、布局分析
·左边是座位的选择区域,左边上部是一些提示信息,主体“2”是展示给用户看的主体部分,所有的数据都是从后台获取。且“2”的布局需要考虑到当行数过多时数据溢出的问题,故需要在其超出显示范围时添加横向滚动跳条。
·右边区域是有关电影和当前场次的一些基本信息,其中“座位”这一栏需要与左边的座位选择区域发生联动关系。是通过一些简单的使事件完成的,这里也就没什么好讲的了。
三、实现过程
1、create-react-app安装
npm install create-react-app -g
具体请参照这个连接:https://segmentfault.com/a/1190000010454922
2、创建项目
creact-react-app choose-seat
3、配置路由
npm install react-router --save
在src目录下创建router文件夹
/src/router/index.js
路由
将创建好的路由注册到路由器中,并挂载在根节点上:
/src/index.js
注册路由
4、添加MockJS库
为了开发的方便,采用mock模拟后台数据,真实使用的时候需要将Mock拦截的请求去掉。
npm install mockjs --save-dev
在src目录下创建mock文件夹并新建index.js
src/mock/index.js
Mock.setup({timeout: '100-300'});//影厅座位信息Mock.mock('/roomInfo',{ data: [ [0,0,0,0,0,2,1,1,1,1,1,1,0,0,0,1,0,1,1], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,2,0,0,0], [1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,0,2,0,0], [1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0] ] });//电影信息Mock.mock('/filmInfo',{ data:{ filmId:1, name: "复仇者联盟3:无限战争", type: "动作,冒险,科幻", duration: "150分钟", cinema: "万达影院", filmRoom: "2号影厅", version: "英语3D", arrange: "今天 5月22 20:00", price: "32.5", poster: "../../assets/img/1.jpg" } })
5、创建座位组件
如图所示,作将index.css与index.js存放到一起,方便到其他项目中进行复用。
组件图
电影座位的实现:
从前文中的mock/index.js中可以看到影厅的座位信息是以二进制数组进行表示的
data: [
[0,0,0,0,0,2,1,1,1,1,1,1,0,0,0,1,0,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,2,0,0,0],
[1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,0,2,0,0],
[1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0]
]
外层数组的长度表示行数,内存数组的长度表示数组的列数,0表示这个位置没有座位,1表示“可选座位”,2表示“已售座位”。
在编排座位的时候的难点主要是一个座位编码的问题,比如第一排有19列却只有10个座位,就要对其进行一次的编号“1排1座”、“1排2座”.......一直到“一排10座”,需要将空位置跳过;并且第二个数组全部都是空格,所以就又涉及到排的跳过。让第三个数组从“2排1座”开始进行编号。我是通过计算数组总和来进行判断的,当然也有更好的方式:
getSum(arr){ return arr.reduce(function(prev, curr, index, arr){ return prev + curr; }); } click(row,column){ let { roomInfo, seatCode, selectSeat } = this.state; if(roomInfo[row][column]===0 || roomInfo[row][column]===2) { return ; } let tmpRoom = _.cloneDeep(roomInfo); let tmpSeat = _.cloneDeep(selectSeat); if(tmpRoom[row][column] === 1 && tmpSeat.length<5) { tmpRoom[row][column] = 3; let code = _.cloneDeep(seatCode[row][column]); tmpSeat.push(code); } else if(tmpRoom[row][column] === 3) { tmpRoom[row][column] = 1; let index = _.findIndex(selectSeat,{row,column}); tmpSeat.splice(index,1); } this.setState({ roomInfo: tmpRoom, selectSeat: tmpSeat }); }
而电影信息从另一个接口中可以拿到数据:
data:{
filmId:1,
name: "复仇者联盟3:无限战争",
type: "动作,冒险,科幻",
duration: "150分钟",
cinema: "万达影院",
filmRoom: "2号影厅",
version: "英语3D",
arrange: "今天 5月22 20:00",
price: "32.5",
poster: "../../assets/img/1.jpg"
}
获得信息后直接展示到界面中来就可以了,代码太多了,我就不贴了。可以再源码里面看到我的具体实现过程。
最后
感谢你能读到这里,这是我第一次正式的写博文,语言组织的不好,希望得到你的谅解。若有什么问题想问我的,我看到以后会马上回复。
作者:尹杭_f685
链接:https://www.jianshu.com/p/9e4efae8b617