前端界面的设计
CourseDetail.cshtml页面
<html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta charset="utf-8"> <title>课程详情</title> <link href="~/css/swiper-bundle.min.css" rel="stylesheet" /> <link href="~/css/couseDetail.css" rel="stylesheet" /> <script src="~/js/swiper-bundle.min.js" type="text/javascript" charset="utf-8"></script> <script src="~/js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="~/js/jquery.js" type="text/javascript" charset="utf-8"></script> </head> <body> <div id="app" class="app" v-cloak> <!-- 已购买课程用户列表 --> <div class="shopUserList"> <!-- 文字走马灯效果实现 --> <div class="home"> <div class="home-box"> <div> <div class="marquee"> <div class="marquee_box"> <ul class="marquee_list" :class="{marquee_top:animate}"> <li v-for="(item, index) in shopUserList" :key="index"> <span>{{item+'购买了该课程'}}</span> </li> </ul> </div> </div> </div> </div> </div> </div> <!-- 轮播图 --> <div class="swiper-banner"> <div class="swiper-wrapper"> <div class="swiper-slide" v-for="(item,index) in carouselList"> <img :src="item"></div> </div> <div class="swiper-pagination"></div> </div> <div class="courseDetail"> <div class="title"> <div class="courseName">@ViewBag.title</div> <div class="coursePrice"> <span>¥</span>{{coursePrice}}</div> </div> <div class="courseList" v-if="courseList&&courseList.length>0"> <div v-for="(item,index) in courseList" :class="item.selected?'active courseItem':' courseItem'" @@click="selected(item.count)"> <div>{{item.count=="all"?"全部":item.count}}</div> <div>{{item.count=="all"?"购买":"节课"}}</div> </div> </div> <div class="other"> <div class="payFreight"> <div class="key">运费 </div> <div class="value">无需配送</div> </div> <hr> <div class="saleCount"> <div class="key">销量</div> <div class="value">@ViewBag.buyNum</div> </div> <hr> <div class="remainCount"> <div class="key">剩余</div> <div class="value">3423</div> </div> </div> <div class="courseIntro"> <div class="courseTitle"> <div class="line"></div><div class="text">课程详情</div><div class="line"></div></div> <div class="picList"> <div class="picItem" v-for="(item,index) in coursePicList"> <img :src="item"> </div> </div> </div> </div> <div class="bottom"> <div class="payPrice">{{"¥"+realityPrice}} </div> <div class="payBtn">立即购买</div> </div> </div> <script type="text/javascript"> var host = "http://kimimath.kyd2002.cn"; //var host = "https://localhost:5001"; var canBuyNum=@ViewBag.canBugNumber; var price = @ViewBag.price; var userId = @ViewBag.userId; var courseId=@ViewBag.courseId; $(function() { var swiper = new Swiper('.swiper-banner', { autoplay: true, pagination: { el: '.swiper-pagination', dynamicBullets: true, }, }); }) var container = new Vue({ el: "#app", data() { return { animate: false, carouselList: ["/image/banner1.png", "/image/banner2.png", "/image/banner3.png", "/image/banner4.png"], shopUserList: ['沫**', '沫**1'], courseList:[], coursePrice: "90.00", coursePicList: [ "/image/details_02.png", "/image/details_03.png", "/image/details_04.png", "/image/detail_05.png" ], realityPrice:0.01, } }, methods: { showMarquee: function() { this.animate = true; setTimeout(() => { this.shopUserList.push(this.shopUserList[0]); this.shopUserList.shift(); this.animate = false }, 1000) }, selected:function(countId){ this.courseList.forEach(function(item){ if(item.count==countId){ item.selected=!item.selected; } else { item.selected=false; } }) var _this = this; var number=@ViewBag.canBugNumber; if (countId != "all") { number = countId; } var url = host + "/api/Order/RealityPrice"; var datas = { userId: userId, curriculumPackageId: courseId, purchaseQuantity: number }; $.ajax({ url: url, type: "Get", data: datas, dataType: "json", success: function (result) { _this.realityPrice = result.Data; } }) }, getcourseList() { var _this = this; var data = { count: "all", selected: false }; var data1 = { count: "3", selected: false }; var data2 = { count: "6", selected: false }; var data3 = { count: "12", selected: false }; var data4 = { count: "24", selected: false }; if (courseId==4) { _this.courseList.push(data); } else if (canBuyNum < 3) { _this.courseList.push(data); } else if (canBuyNum < 6) { _this.courseList.push(data1); _this.courseList.push(data); } else if (canBuyNum < 12) { _this.courseList.push(data1); _this.courseList.push(data2); _this.courseList.push(data); } else if (canBuyNum < 24) { _this.courseList.push(data1); _this.courseList.push(data2); _this.courseList.push(data3); _this.courseList.push(data); } else { _this.courseList.push(data1); _this.courseList.push(data2); _this.courseList.push(data3); _this.courseList.push(data4); _this.courseList.push(data); } }, GetPrice() { if (price > 90) { if (courseId == 4) { this.coursePrice = price; } else { this.coursePrice = "90 -" + price; } } else { this.coursePrice = price; } }, }, mounted() { this.getcourseList(); this.getPrice(); setInterval(this.showMarquee, 2000); }, }) </script> </body> </html>
couseDetail.css
html, body { position: relative; height: 100%; font-family: "Microsoft YaHei"; } html { font-size: 16px; } body { margin: 0; padding: 0; } [v-cloak] { display: none; } /* 轮播样式 */ .swiper-banner { width: 100%; height: 300px; position: relative; overflow-x: hidden; } .swiper-slide { width: 100%; height: 100%; } .swiper-slide img { width: 100%; height: auto; max-height: 100%; } .shopUserList { position: fixed; top: 26px; width: 40%; height: 40px; border-radius: 0px 30px 30px 0px; z-index: 10; z-index: 10; background: rgba(0, 0, 0, 0.7); } /* 走马灯效果实现 */ .home { height: 100%; width: 100%; display: flex; justify-content: center; align-items: center; } .home-box { width: 100%; height: 100%; } .marquee { width: 100%; height: 100%; align-items: center; display: flex; box-sizing: border-box; } .marquee_box { display: block; position: relative; width: 100%; height: 40px; overflow: hidden; } .marquee_list { display: block; position: absolute; top: 0; left: 0; list-style: none; padding: 0; margin: 0; width: 100%; height: 100%; } .marquee_top { transition: all 0.5s; margin-top: -40px } .marquee_list li { height: 100%; padding: 0 5px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; } .marquee_list li span { font-size: 13px; font-size: 0.8125rem; color: #ffffff; } /* 课程详情样式 */ .courseDetail { padding-top: 20px; box-sizing: border-box; padding-bottom: 55px; } .courseDetail .title { margin-bottom: 10px; } .courseDetail .title, .courseDetail .courseList { padding: 0 10px; box-sizing: border-box; display: flex; } .courseDetail .courseName, .courseDetail .coursePrice { display: flex; align-items: center; height: 100%; } .courseDetail .courseName { width: 80%; justify-content: flex-start; } .courseDetail .coursePrice { width: 60%; color: #ff4e00; justify-content: flex-end; font-weight: bold; font-size: 24px; font-size: 1.5rem; } .courseDetail .coursePrice span { font-size: 14px; font-size: 0.875rem; padding-right: 2px; box-sizing: border-box; } .courseName { color: #1e3276; font-size: 18px; font-size: 1.125rem; } .courseDetail .courseList { flex-wrap: wrap; justify-content: space-between; flex-wrap: wrap; } .courseList .courseItem { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 60px; margin-right: 5px; height: 60px; border-radius: 12px; border: solid 1px #a6a7ff; color: #1e3276; margin-bottom: 10px; font-weight: bold; } .courseList .active{ background-color: #ff4e00; color: #fff; border: none; } .courseList .courseItem, .courseDetail .other, .courseIntro .text{ font-size: 15px; font-size: 0.9375rem; } .courseIntro hr { display: inline; height: 30%; } /* 运费等 */ .courseDetail .other { background-color: #f2f2ff; display: flex; height: 50px; margin-top: 10px; flex-direction: row; flex-wrap: nowrap; justify-content: center; align-items: center; padding: 0 10px; } .payFreight, .saleCount, .remainCount { height: 100%; display: flex; justify-content: center; align-items: center; } .other hr { height: 30%; } .other .key { padding-right: 5px; box-sizing: border-box; color: #6d6d9a; } .other .value, .courseIntro .text { color: #1e3276; font-weight: bold; } .picList { width: 100%; } .picList img { width: 100%; height: auto; } .courseTitle { width: 80%; height: 50px; display: flex; align-items: center; margin: 0 auto; justify-content: space-between; } .courseTitle .line { width: 30%; height: 100%; height: 1px; background-color: #e6e5ff; } .bottom { position: fixed; bottom: 0; width: 100%; height: 55px; background-color: #ff4800; border-radius: 20px 20px 0px 0px; padding: 0 20px; box-sizing: border-box; display: flex; justify-content: space-between; align-items: center; font-weight: bold; } .payPrice { height: 100%; display: flex; justify-content: flex-start; align-items: center; width: 30%; color: #ffffff; font-size: 23.5px; font-size: 1.46875rem; } .payBtn { width: 32%; height: 65%; display: flex; background-color: yellow; justify-content: center; align-items: center; background-color: #ffffff; border-radius: 27px; color: #fe6d52; font-size: 15.5px; font-size: 0.96875rem; }
CourseList.cshtml 页面
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta charset="utf-8"> <title>课程列表</title> <link rel="stylesheet" type="text/css" href="~/css/courseList.css" /> <link href="~/js/layer/theme/default/layer.css" rel="stylesheet" /> </head> <body> <div id="app" class="app" v-cloak> <div class="dialog" v-if="showDialog" v-cloak> <div class="mask"> <div class="maskContent"> <img src="/image/del_press.png" class="closeBtn" @@click="closeDialog"> <img src="/image/popup_img_bg.png" class="dialogBg"> <div class="submitContent" > <div class="title"> <div>请使用购买课程的手机号码</div> <div>登录奇米儿童数学APP</div> </div> <form> <div class="phoneNum"> <input type="number" placeholder="请输入手机号" maxlength="11" v-model="phone" /> </div> <div class="verity"> <div class="verityCode"><input type="number" placeholder="请输入验证码" v-model="verifyCode" /></div> <div class="verityBtn" @@click="getCode">{{SendverifyCode}}</div> </div> <div class="checkbox" @@click="choice"> <div><img :src="selected?'/image/pay_jcon_selected.png':'/image/pay_jcon_unselected.png'"></div> <div>绑定我的手机号到该公众号</div> </div> <div class="submit" @@click="submit">提交</div> </form> </div> </div> </div> </div> <div class="container"> <img src="/image/banner.png" class="banner"> <div class="courseList"> <div class="item" v-for="(item,index) in courseList" @@click="jumpDetail(item.Id,item.Title,item.BuyNum,item.CanBugNumber,item.Price )"> <img :src="item.VerticalIconUrl"> <div class="courseName">{{item.Title}}</div> <div class="price"> <div class="nowPrice"><span>¥</span>{{item.Price}}</div> <div class="prePrice">{{"原价¥"+item.OriginalPrice}}</div> </div> </div> </div> <img src="/image/logo.png" class="logo"> </div> </div> <script src="~/js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="~/js/jquery.js" type="text/javascript" charset="utf-8"></script> <script src="~/js/layer/layer.js"></script> <script type="text/javascript"> var openId ="@ViewBag.OpenId"; var host = "http://kimimath.kyd2002.cn"; //var host = " http://192.168.100.3:33003"; var container = new Vue({ el: "#app", data() { return { showDialog: true, selected: false, courseList:[], phone: "", SendverifyCode: "发送验证码", time: 120, //验证码发送的间隔(秒) verifyCode: "", submitContent: true, userId: '', } }, methods: { choice: function () { this.selected = !this.selected; }, closeDialog: function () { this.showDialog = false; }, jumpDetail: function (id, title, buyNum,canBugNumber,price) { var href = "/Team/WXPay?userId=" + this.userId + "&openId=" + openId + "&courseId=" + id + "&title=" + title + "&buyNum=" + buyNum + "&canBugNumber=" + canBugNumber + "&price=" + price; window.location.href = href; }, getCode() { var _this = this; var url = host + "/api/UserInfo/SendVerifyCode?phone=" + _this.phone + ""; $.ajax({ url: url, type: "POST", async: true, success: function (result) { if (result.Code == 1) { var interval = window.setInterval(function () { _this.SendverifyCode = '(' + _this.time + '秒)后重发'; _this.time--; if (_this.time < 0) { _this.SendverifyCode = "发送验证码"; _this.time = 120; window.clearInterval(interval); } }, 1000); } else { if (result.Code == 7) { layer.alert('手机号格式不正确, 请输入正确的手机号码!'); } else if (result.Code == 13) { layer.alert('短信发送失败,请稍后重试!'); } else { layer.alert('服务器异常,请稍后重试!'); } } } }) }, submit() { var _this = this; var webPage = true; var url = host + "/api/UserInfo/Register?phone=" + _this.phone + "&verificationcode=" + _this.verifyCode + "&webPageClient=" + webPage; $.ajax({ url: url, type: "POST", dataType: "json", contentType: "application/json", success: function (result) { if (result.Code == 1) { _this.userId = result.Data.Id; _this.GetCourseList(); if (_this.selected == true) { var dataBing = { phone: _this.phone, openId: openId }; var urlhome = "/home/BingOpenId"; $.ajax({ url: urlhome, type: "POST", dataType: "json", async: true, data: dataBing, success: function (res) { if (res == 1) { _this.showDialog = false; } } }) } else { _this.showDialog = false; } } else { //注册异常处理 if (result.Code == 4) { layer.alert('手机号或验证码缺失,请填写完整!'); } else if (result.Code == 9) { layer.alert('未发送验证码!'); } else if (result.Code == 10) { layer.alert('验证码已过期!'); } else if (result.Code == 8) { layer.alert('验证码错误!'); } else { layer.alert('服务器异常,请重新发送验证码'); } } } }); }, GetCourseList() { var _this = this; var userId = _this.userId; var url = host + "/api/Course/ProductList"; var data = { userId: userId }; $.ajax({ url: url, data: data, dataType: "json", type: "GET", success: function (result) { var list = result.Data.curriculumPackageDtoList; var newList = list.sort(function (a, b) { return a.Id - b.Id }); newList.pop(); _this.courseList = newList; } }) }, JudgeIsBindPhone() { var _this = this; var url = "GetUserId?openId=" + openId; $.ajax({ url: url, type: "POST", dataType: "JSON", success: function (result) { if (result != 0) { _this.showDialog = false; _this.userId = result; _this.GetCourseList(); } else { _this.showDialog = true; } } }) }, }, mounted() { this.JudgeIsBindPhone(); // 页面开始加载时修改font-size var html = document.getElementsByTagName("html")[0]; var oWidth = document.body.clientWidth || document.documentElement.clientWidth; // 这里的750是指设计图的大小,自己根据实际情况改变 html.style.fontSize = oWidth / 750 * 30 + "px"; console.log('rem:', html.style.fontSize); } }) </script> </body> </html>
courseList.css
body { padding: 0; margin: 0; } /* 弹框效果 */ .dialog { position: fixed; width: 100%; height: 100%; z-index: 1; } .mask { width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); display: flex; position: relative; } .closeBtn { position: absolute; top: 10%; right: 10px; width: 20px; height: auto; z-index: 10; } .maskContent { width: 85%; height: 500px; display: flex; align-self: center; position: relative; justify-content: center; align-items: center; margin: 0 auto; } .dialogBg { position: absolute; top: 0; width: 100%; height: auto; max-height: 100%; z-index: 3; } .submitContent { position: absolute; top: 15%; width: 100%; height: 90%; z-index: 4; } .submitContent .title { width: 100%; text-align: center; margin: 0 auto; color: #000000; font-size: 16px; font-size: 1rem; } form { width: 100%; height: 100%; margin-top: 10px; } .phoneNum { width: 90%; height: 40px; margin: 0 auto; display: flex; justify-content: center; align-items: center; } .phoneNum input { width: 100%; height: 100%; border-radius: 41px; border: solid 1px #d2d0ef; padding: 0 10px; box-sizing: border-box; text-align:center } input { border: none; outline: none; } .verity { display: flex; width: 90%; justify-content: space-between; height: 40px; margin: 0 auto; margin-top: 15px; } .verity .verityCode { width:50%; height: 100%; } .verity input { width: 100%; height: 100%; border-radius: 41px; border: solid 1px #d2d0ef; padding: 0 10px; text-align:center; } .verityBtn { width: 40%; height: 100%; background-color: #e8e6ff; border-radius: 41px; display: flex; justify-content: center; align-items: center; color: #7f7bb8; } .checkbox { display: flex; width: 80%; margin: 0 auto; height: 40px; align-items: center; margin-top: 10px; color: #969696; font-size: 14px; font-size: 0.875rem; } .checkbox img { width: 35px; height: auto; padding-right: 10px; box-sizing: border-box; } .submit { width: 90%; height: 40px; margin: 0 auto; margin-top: 5px; background-color: #fd7c48; border-radius: 41px; display: flex; align-items: center; justify-content: center; color: #ffffff; font-size: 18px; font-size: 1.125rem; } /*top */ .container { width: 100%; padding-bottom: 20px; } .container .banner { display: block; width: 100%; height: auto; } .courseList { padding: 12px; box-sizing: border-box; display: flex; flex-wrap: wrap; justify-content: space-between; } .courseList .item { width: 47%; margin-bottom: 20px; } .courseList .courseName { margin-top: 5px; font-size: 16.8px; font-size: 1.05rem; color: #585858; } .courseList img { display: block; width: 100%; height: auto; border-radius: 10px; } .courseList .price { margin-top: 5px; display: flex; justify-content: space-between; align-items: center; } .nowPrice { color: #ff3600; font-weight: bold; font-size: 18px; font-size: 1.125rem; } .nowPrice span { font-size: 14px; } .courseList .prePrice { text-decoration: line-through; color: #979797; font-size: 14px; font-size: 0.875rem; } .logo{ width:30%; height: auto; display: block; margin: 0 auto; } .Message { height: 50%; justify-content: center; align-items: center; display: flex; font-size: 20px; }
下载layer时,要整个包都导入,否则会报错找不到文件(虽然这个报错不影响整体,看着不舒服)
2 遇到的一些问题
在方法中定义 var _this=this;
_this只是一个变量名,this代表父函数,如果在子函数(比如ajax中的success)还用this,this的指向就变成子函数了