继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

React仿猫眼电影选座组件

潇潇雨雨
关注TA
已关注
手记 305
粉丝 25
获赞 130

最近几个月一直在做自己的毕业设计,仿照猫眼完成一整套的电影订票系统,整个系统由React网页端、ReactNative的手机端、Node的服务端和管理系统组成。虽然是完成了,但是因为自己还在忙着实习的工作,所以有些地方做得很粗糙。这几天空闲下来打算把自己的代码整理一下,梳理一下知识结构同时也想和更多人交流技术。

组件分析

猫眼官网上的电影选座组件截图如下:

https://img2.mukewang.com/5d308630000138ad06860319.jpg

原图

为了讲解的方便,我对图中的一些部分进行了标号。具体分析如下:

一.、座位分析

从“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

https://img1.mukewang.com/5d3086340001744506280335.jpg

路由

将创建好的路由注册到路由器中,并挂载在根节点上:

    /src/index.js

https://img3.mukewang.com/5d30863900012d2106380395.jpg

注册路由

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存放到一起,方便到其他项目中进行复用。


https://img2.mukewang.com/5d30863e0001749802760571.jpg

组件图

电影座位的实现:

从前文中的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


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP