首页IT科技不是吧阿sir表情图(不是吧,阿sir,还有人不会制作影院订票系统前端页面吗?(拿来就用))

不是吧阿sir表情图(不是吧,阿sir,还有人不会制作影院订票系统前端页面吗?(拿来就用))

时间2025-06-28 07:13:57分类IT科技浏览3938
导读:引言:   大家好,欢迎来到我的博客。五一假期就快到了,你们准备怎么安排假期活动呢?要不去看一场电影来缓解一下枯燥的学习生活?😝说起电影,就离不开中国内地电影票房冠军《长津湖》。那么今天,我们就来制作一个影院订票系统前端页面,如有错误之处,欢迎大家指正。😊...

引言:   大家好           ,欢迎来到我的博客          。五一假期就快到了                ,你们准备怎么安排假期活动呢?要不去看一场电影来缓解一下枯燥的学习生活?😝说起电影      ,就离不开中国内地电影票房冠军《长津湖》                 。那么今天     ,我们就来制作一个影院订票系统前端页面                ,如有错误之处           ,欢迎大家指正      。😊

🎉案例分析

  影院订票系统是电影院进行电影票销售非常重要的一个环节     ,直接影响到用户的操作是否方便          、界面是否直观          。该系统包括用户注册                 、影片信息管理      、订票信息管理          、站内新闻管理等模块                。本节仅对其中的订票前端页面进行阐述                ,目的是让读者能对本书前期学习的知识进行综合运用           ,本节完成的前端页面如图1所示,可点击效果动图查看完成效果      。

图1 效果图

  该页面要求用图形方式进行座位的选择                ,也就是能够单击图1左边的可选座位来选中想购买的座位                ,单击可选座位之后,该座位会变成已选座位状态;单击已选座位后           ,该座位会重新回到可选座位状态;图中灰色的座位表示已是售出座位的状态     。

  另外                ,选中或取消某一个座位之后      ,在图1的右边会自动显示出已选座位是“几排几号           ”           ,并能根据用户所选择的电影票张数                ,自动计算出本次购票的总价      ,同时还能限制用户最多一次只能购买五张电影票     ,当票数达到上限时                ,动态提示用户           ,此时不能再选择新的可选座位     ,但可以取消已选座位                。

  由图1可以看出该页面分为左右两个部分                ,采用Bootstrap栅格布局实现           ,即左右各占12等份的一半,其中左半部分又分成两行(座位行和座位提示行)                ,右半部分也分成两行(电影信息行和影票购买信息行)                ,其实现代码如下所示:

<div class="container" id="app"> <div class="row"> <div class="col-md-6"> <div class="row"> <!--左上半部分:座位行--> </div> <div class="row"> <!--左下半部分:座位提示行--> </div> </div> <div class="col-md-6 sceenRight"> <div class="row"> <!--右上半部分:电影信息行--> </div> <div class="row"> <!--右下半部分:影票购买信息行--> </div> </div> </div> </div>

🎉详细设计

✨座位数据与样式定义

  座位数据是通过在<li></li>标记中使用背景图片,背景图片有四种座位样式:无座位(空白)                、可选座位(白色)      、选中座位(红色)     、售出座位(灰色)           ,在数组中定义的数值如下:

-1:无座位0:可选座位1:选中座位2:售出座位

  例如                ,在Vue.js中定义一个11行10列的座位      ,每个座位用一个数字来表示           ,数字含义如上所示                ,定义的数组语句如下所示(其在浏览器中对应如图1左上半部分的座位图):

seatflag:[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, ]

  从定义的seatfage数组可以看出这是一维数组      ,让其变成能够显示行列的二维数组的方法是:定义一行有多少座位的数据seatCol     ,用户单击某一个座位后                ,在程序中可以得到该座位在数组中的序号           ,该序号整除seatCol得到的商就是行号     ,对seatCol取余数就是相对应的列号           。

在CSS中对座位<li>元素的样式定义是通过四个座位的背景图(如图2所示)完成                ,通过上下移动该背景图使用户在<li>元素的窗口中看到不同的座位样式           ,其样式定义如下所示:

图2 订票系统座位背景图

.seat{ float: left; width: 30px; height: 30px; background-color: bisque; margin: 5px 10px; cursor: pointer; list-style: none; } .seatActive{ background: url(img/bg.png) 1px 0px; } .seatSpace{ background: url(img/bg.png) 1px -29px; } .seatNoUse{ background: url(img/bg.png) 1px -56px; } .noSeat{ background: url(img/bg.png) 1px -84px; }

  使用Vue中的v-for命令对上面的数据动态生成多个座位的<li>元素     。每个座位都有“seat                ”样式类,然后根据每个座位对应的数据来显示其对应的样式图片                ,当对应座位的数据是-1时                ,添加“noSeat      ”样式类,即没有该座位;当对应座位数据是0时           ,添加“seatSpace     ”样式类                ,即该座位是可选座位;当对应座位数据是1时      ,添加“ seatActive                 ”样式类           ,即该座位是已选座位;当对应座位数据是2时                ,添加“seatNoUse           ”样式类      ,即该座位是售出座位                。HTML中的语句如下所示:

<li class="seat seatSpace" v-for="(item,index) in seatflag" :key="index" :class="{noSeat:seatflag[index]==-1, seatActive:seatflag[index]==1, seatSpace:seatflag[index]==0, seatNoUse:seatflag[index]==2, }", @click="handleClick(index)" ></li>

  行和列是由单击座位对应序号和数据seatCol来确定的     ,但在浏览器中的显示是由<li>的父级元素来确定的                ,也就是<ul>元素的宽度           ,这些数据以后都可以通过后台服务器动态获取           。该<ul>元素的样式定义如下所示:

#app ul{ list-style: none;/*去除列表样式*/ width: 550px;/*设定宽度,目的是一行显示多少座位,其他座位另起新行*/ }

✨座位的事件处理及相关的代码

  用户单击某个座位后     ,会执行相应座位的单击事件处理函数handleClick(index)                ,处理函数的入口参数index是用户单击某个座位在一维数组seatflag中的位置值           ,利用Vue中的数据绑定,当用户修改了数组seatflag的数据值                ,会自动刷新相对应的座位图片。该函数的实现方式如下所示:

handleClick:function(index){ if (vm.seatflag[index]==1){ vm.$set(vm.seatflag,index,0); //console.log(this.curSeat.findIndex(item=>item.id===index)); this.curSeat.splice(this.curSeat.findIndex(item=>item===index),1); } else if (vm.seatflag[index]==0 && this.count<5){ vm.$set(vm.seatflag,index,1); this.curSeat.push(index); } //设置当前选中的座位 this.curSeatDisp=[]; for(let item of this.curSeat){ this.curSeatDisp.push((Math.floor(item/this.seatCol)+1)+"行"+(item%this.seatCol+1)+"列"); } //计数已经选择了多少个座位 var mySeat=vm.seatflag.filter(item=>{//item为数组当前的元素 return item==1; }) this.count=mySeat.length; //判断达到购买上限                ,设置数据maxFlag,并显示提示语句           ,并显示提示语句“您一次最多仅能买五张票     ” if (this.count>=5)this.maxFlag=true; else this.maxFlag=false; }

  说明如下:

  (1)显示已选座位“几排几列                ”是根据 curSeatDisp 数组确定                ,在HTML中通过v-for指令实现      ,其代码如下所示:

<p id="seatSelect"> 座位: <span v-for="(item,index) in curSeatDisp" :key="index"> {{item}} </span> </p>

  (2)显示已选择多少个座位是根据count数据确定           ,在HTML中的实现代码如下所示:

<p>已选择 <strong style="color: red;">{{count}}</strong>个座位                , </p>

  (3)判断达到购买票数上限后      ,是否显示“您一次最多仅能买五张票           ”的提示语句     ,通过数据maxFlag的值确定                。在HTML中的语句如下所示:

<strong style="color: red;">再次单击座位可取消                 。 <span v-if="maxFlag">您一次最多只能买五张票!</span> </strong>

✨监听与数据格式化

  在Vue中通过监听count数据的变化                ,可以重新计算总价。在Vue实例中的语句如下所示:

computed:{ totalPrice:function(){ return this.count * this.filmInfo.unitPrice; } },

  显示电影票单价和总价通过Vue的全局过滤器实现           ,让其保留两位小数点     ,并在金额前面加上人民币符号          。在Vue实例中的语句如下所示:

Vue.filter(numberFormat,function(value){ return +value.toFixed(2) })

  在HTML中使用过滤器是通过管道符实现的                ,其代码如下所示:

<p>单价: <strong>{{filmInfo.unitPrice|numberFormat}}</strong> </p> <p>总价: <strong style="color: red;">{{totalPrice|numberFormat}}</strong> </p>

✨电影信息展示

  图1的右上半部分是电影海报和电影的部分相关信息           ,这部分是通过调用Vue实例的filmInfo对象中的相关数据来显示信息                 。flmInfo对象在Vue的data中的定义如下:

fileInfo:{ name:长津湖, nameEnglish:The Battle at Lake Changjin, copyRight:中文2D, filmImg:img/1.png, storyType:历史                、战争, place:中国大陆, timeLength:176 分钟, timeShow:2021年9月30日, cinema:万达影城, room:1号影厅, time:2021年9月30日 20:00, unitPrice:38, }

  此处HTML的实现方式是使用Bootstrap提供的媒体对象组件,代码如下所示:

注:可在bootstrap官网直接映入媒体对象组件      。操作方式:打开bootstrap官网(https://www.bootcss.com/)                ,点击页面最中心Bootstrap3中文文档(v3.4.1),选择右侧列表中的“媒体对象”                ,复制代码即可          。

<div class="row"> <!--右上半部分:电影信息行--> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" :src="filmInfo.filmImg" alt="..." height="200px"> </a> </div> <div class="media-body"> <h4 class="media-heading">中文名:<strong>{{filmInfo.name}}</strong></h4> <h4 class="media-heading">英文名:<strong>{{filmInfo.nameEnglish}}</strong></h4> <p>剧情:{{filmInfo.storyType}}</p> <p>版本:{{filmInfo.copyType}}</p> <p>{{filmInfo.place}}/{{filmInfo.timeLength}}</p> <p>{{filmInfo.timeShow}}</p> </div> </div> </div>

  这里在HTML中进行数据绑定时使用了两种方式,一种是双大括号的数据绑定方式           ,即“{{数据}}                ”;另一种是属性绑定方式                ,

即“:src=filmInfo.film Img                ”                。

🎉动态操作演示图

动态操作演示

  总结:本章主要讲解了影院订票系统前端页面的综合案例      ,重点是使用Vue. js的特性结合Bootstrap的排版功能实现           ,该案例要求具有较高的 JavaScript 程序的编程能力和对Vue. js进行网页行为的控制能力      。通过这个案例的学习                ,读者不仅可以更进一步           、更深刻地理解前面章节学过的所有知识      ,而且能够体会到最新前端框架Vue. js的数据渲染     、事件触发响应                、监听属性           、计算属性、各种指令等在实际项目中的灵活应用     ,以及Bootstrap的简便布局排版能力     。

🎉源码(附图片素材)

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <link href="./css/bootstrap.min.css" rel="stylesheet"> <script src="js/vue.min.js"> </script> <style> #app{ margin: 50px auto; } #app ul{ list-style: none; width: 550px; } #app ul #screen{ text-align: center; letter-spacing: 30px; } .seat{ float: left; width: 30px; height: 30px; background-color: bisque; margin: 5px 10px; cursor: pointer; list-style: none; } .seatActive{ background: url(img/bg.png) 1px 0px; } .seatSpace{ background: url(img/bg.png) 1px -29px; } .seatNoUse{ background: url(img/bg.png) 1px -56px; } .noSeat{ background: url(img/bg.png) 1px -84px; } .notice{ float: left; height: 30px; line-height: 30px; margin-right: 70px; } </style> </head> <body> <div class="container" id="app"> <div class="row"> <div class="col-md-6"> <div class="row"> <!--左上半部分:座位行--> <ul> <li id="screen"> <h1>屏幕</h1> </li> <hr> <!--<li class="seat seatActive"></li>--> <li class="seat seatSpace" v-for="(item,index) in seatflag" :key="index" :class="{noSeat:seatflag[index]==-1, seatActive:seatflag[index]==1, seatSpace:seatflag[index]==0, seatNoUse:seatflag[index]==2, }",@click="handleClick(index)" ></li> <!--<li class="seat seatNoUse"></li>--> <!--<li class="seat noSeat" ></li>--> </ul> </div> <div class="row"> <!--左下半部分:座位提示行--> <hr> <li class="seat seatActive"></li> <span class="notice">已选座位</span> <li class="seat seatSpace"></li> <span class="notice">可选座位</span> <li class="seat seatNoUse"></li> <span class="notice">售出座位</span> </div> </div> <div class="col-md-6 sceenRight"> <div class="row"> <!--右上半部分:电影信息行--> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object" :src="filmInfo.filmImg" alt="..." height="200px"> </a> </div> <div class="media-body"> <h4 class="media-heading">中文名:<strong>{{filmInfo.name}}</strong></h4> <h4 class="media-heading">英文名:<strong>{{filmInfo.nameEnglish}}</strong></h4> <p>剧情:{{filmInfo.storyType}}</p> <p>版本:{{filmInfo.copyType}}</p> <p>{{filmInfo.place}}/{{filmInfo.timeLength}}</p> <p>{{filmInfo.timeShow}}</p> </div> </div> </div> <div class="row"> <!--右下半部分:影票购买信息行--> <p>影院:<strong>{{filmInfo.ciname}}</strong></p> <p>影厅:<strong>{{filmInfo.room}}</strong></p> <p>场次:<strong>{{filmInfo.time}}</strong></p> <p id="seatSelect">座位:<span v-for="(item,index) in curSeatDisp" :key="index">{{item}}</span></p> <p>已选择<strong style="color: red;">{{count}}</strong>个座位                ,<strong style="color: red;">再次单击座位可取消                。 <span v-if="maxFlag">您一次最多只能买五张票!</span></strong></p> <hr> <p>单价:<strong>{{filmInfo.unitPrice|numberFormat}}</strong></p> <p>总价:<strong style="color: red;">{{totalPrice|numberFormat}}</strong></p> <hr> <button type="button" class="btn btn-success" style="margin: 0 200px;" @click="filmSubmit">确认信息           ,下单</button> </div> </div> </div> </div> <script> Vue.filter(numberFormat,function(value){ return +value.toFixed(2) }) var vm=new Vue({ el:#app, data:{ curSeat:[],//选中座位数组 curSeatDisp:[],//选中座位展示数组 count:0,//当前已选中票的个数 maxLength:5,//一次最多可购买的张数 maxFlag:false,//是否允许再选择票数 seatCol:10,//一行的座位列数     ,当前是10列 seatflag:[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, ], filmInfo:{ name:长津湖, nameEnglish:The Battle at Lake Changjin, copyRight:中文2D, filmImg:img/1.png, storyType:历史                、战争, place:中国大陆, timeLength:176 分钟, timeShow:2021年9月30日, cinema:万达影城, room:1号影厅, time:2021年9月30日 20:00, unitPrice:38, } }, computed:{ totalPrice:function(){ return this.count * this.filmInfo.unitPrice; } }, methods:{ handleClick:function(index){ if (vm.seatflag[index]==1){ vm.$set(vm.seatflag,index,0); //console.log(this.curSeat.findIndex(item=>item.id===index)); this.curSeat.splice(this.curSeat.findIndex(item=>item===index),1); } else if (vm.seatflag[index]==0 && this.count<5){ vm.$set(vm.seatflag,index,1); this.curSeat.push(index); } //设置当前选中的座位 this.curSeatDisp=[]; for(let item of this.curSeat){ this.curSeatDisp.push((Math.floor(item/this.seatCol)+1)+"行"+(item%this.seatCol+1)+"列"); } //计数已经选择了多少个座位 var mySeat=vm.seatflag.filter(item=>{//item为数组当前的元素 return item==1; }) this.count=mySeat.length; //判断达到购买上限                ,设置数据maxFlag           ,并显示提示语句,并显示提示语句“您一次最多仅能买五张票” if (this.count>=5)this.maxFlag=true; else this.maxFlag=false; } } }) </script> </body> </html>

图片:

bg.png

谢谢大家                ,请多多支持!

声明:本站所有文章                ,如无特殊说明或标注,均为本站原创发布           。任何个人或组织           ,在未征得本站同意时                ,禁止复制                 、盗用、采集          、发布本站内容到任何网站                 、书籍等各类媒体平台     。如若本站内容侵犯了原著者的合法权益      ,可联系我们进行处理                。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
最新做任务赚钱的平台有哪些(有什么好的做任务赚钱的平台-网创任务平台) bcc-tools(bccmd命令 – CSR BCCMD接口的实用程序)