吴裕雄--天生自然WEB前端开发实战--电影院购票

<!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;
            }
            .seatNo{
                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" v-for="(item,index) in seatflag"
                            :key="index" 
                            :class="{'seatNo':seatflag[index]==-1,
                                    'seatSpace':seatflag[index]==0,
                                    'seatActive':seatflag[index]==1,
                                    'seatNouse':seatflag[index]==2
                                    
                            }"
                            >
                                
                            </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">
                    <div class="row">
                        <!--右上半部分:电影信息行-->
                    </div>
                    <div class="row">
                        <!--右下半部分:影票购买提示-->
                    </div>
                </div>
                
            </div>
        </div>
        <script>
            var vm=new Vue({
                el:'#app',
                data:{
                    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,
                    ]
                }
            })
        </script>
    </body>
</html>
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>购票</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <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: 20px;
        }

        .seat {
            float: left;
            width: 30px;
            height: 30px;
            background-color: bisque;
            margin: 5px 10px;
            /* background: url("img/bg.png") no-repeat 1px -29px; */
            cursor: pointer;
        }

        .seatNotice {
            float: left;
            width: 30px;
            height: 30px;
            margin: 5px 10px;
            background-color: bisque;
            list-style: none;
            margin-left: 50px;
        }

        .notice {
            float: left;
            height: 30px;
            line-height: 30px;

        }

        .seatSpace {
            background: url("img/bg.png") no-repeat 1px -29px;
        }

        .seatActive {
            background: url("img/bg.png") 1px 0px;
        }

        .seatNoUse {
            background: url("img/bg.png") 1px -56px;
        }

        .noSeat {
            background: url("img/bg.png") 1px -84px;
        }



        #filmInformation h4,
        #filmInformation p {
            font-size: 20px;
            margin-left: 15px;
            margin-bottom: 14px;
        }

        #filmInformation p {
            font-size: 16px;
            margin-left: 15px;
        }

        .sceenRight {
            background-color: bisque;
            height: 650px;
            padding-top: 10px;
        }

        .sceenRight>p {
            color: red;
            font-size: 28px;

        }

        .filmCurrent {
            font-size: 16px;
            margin: 5px;
        }

        .filmCurrent p {
            margin: 15px;
        }

        #seatSelect span {
            padding: 5px;
            border: 1px solid red;
            margin: 8px;
            font-size: 14px;
            background-color: white;
            font-weight: bold;
            color: red;
        }
    </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 v-for="(item, index) in seatflag" :key="index" class="seat"
                            :class="{'noSeat' : seatflag[index]==-1,'seatSpace' : seatflag[index]==0,'seatActive' : seatflag[index]==1,'seatNoUse' : seatflag[index]==2}"
                            @click="handleClick(index)">
                        </li>
                    </ul>
                </div>
                <div class="row">
                    <hr>
                    <li class="seatNotice seatActive"></li> <span class="notice">已选座位</span>
                    <li class="seatNotice seatSpace"></li> <span class="notice">可选座位</span>
                    <li class="seatNotice seatNoUse"></li> <span class="notice">售出座位</span>
                </div>
            </div>
            <div class="col-md-6 sceenRight">
                <div class="row">
                    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
                        <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" id="filmInformation">
                                <h4 class="media-heading">中文名:<strong>{{filmInfo.name}}</strong></h4>
                                <h4 class="media-heading">英文名:{{filmInfo.nameEnglish}}</h4>
                                <p>剧情:{{filmInfo.storyType}}</p>
                                <p>版本:{{filmInfo.copyRight}}</p>
                                <p>{{filmInfo.place}} / {{filmInfo.timeLength}}</p>
                                <p>{{filmInfo.timeShow}}</p>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row filmCurrent">
                    <p>影院:<strong>{{filmInfo.cinema}}</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列
                //totalPrice: 0,         //售票总价
                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: 'Lost in Russia',      // 影片英文名
                    copyRight: '中文2D',                //版本
                    filmImg: 'img/film1.png',               // 影片海报文件名
                    storyType: '喜剧',                  // 影片类型 
                    place: '中国大陆',                  // 影片产地 
                    timeLength: '126分钟',              // 影片时长
                    timeShow: '2020.02',                // 影片上映时间
                    cinema: '万达影城',                 // 电影院
                    room: '8号影厅',                    // 放映影厅
                    time: '2020.05.18(周一)20:00',     //放映时间
                    unitPrice: 38,                      //单价
                }
            },
            computed: {
                totalPrice: function () {
                    //console.log( this.count * this.filmInfo.unitPrice);
                    return this.count * this.filmInfo.unitPrice;
                }
            },
            methods: {
                filmSubmit: function () {
                    //向服务器提交数据,此处省略

                },
                handleClick: function (index) {

                    //对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
                    //seatflag数组元素值的含义是:0:未售出,白色;1:已选中,红色;2:已售出,灰色
                    //改变座状态,由选中到不选中或者相反操作。

                    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;

                    //判断达到购买上限
                    if (this.count >= 5) this.maxFlag = true;
                    else this.maxFlag = false;
                }
            }

        });
    </script>
</body>

</html>

 

 

原文地址:https://www.cnblogs.com/tszr/p/13871385.html