钢琴约课小程序(微信小程序原生,含用户端和教师端)
技术:微信小程序、html+js
概述
钢琴约课小程序(微信小程序原生,含用户端和教师端),包含排课页面、课程详情、请假、登录、注册、个人中心等。里面是已调用了接口,静态的话,把走接口的数据用静态数据代替即可。
详细
注意:
钢琴约课小程序(微信小程序原生,含用户端和教师端),包含排课页面、课程详情、请假、登录、注册、个人中心等。里面是已调用了接口,静态的话,把走接口的数据用静态数据代替即可。
1、项目结构图
以下对小程序界面解析介绍:
2、app.css的样式重置封装使用
重要部分如下:
/** 显示方式 */ .dis-f {display: -webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex;} .dis-b{ display: block;} .dis-ib{ display: inline-block;} .dis-i{ display: inline;} /** 背景颜色 */ .bg-greenlack { background: black;} .bg-o { background: #ff9018;} .bg-r { background: #ff2200;} .bg-yellow { background:linear-gradient(to right, #fbca30, #f3b220);} .bg-green { background:linear-gradient(to right, #49bf71,#55d67f, #2cb659);} .bg-gray { background: #7f8699;} .bg-w{ background: #ffffff; overflow: hidden;} .bg-3{ background: #f3f3f3; overflow: hidden;} .bg-pri{ background: #ff6905;} .bor{ border:1px solid #f6f6f6;} .bor-t{ border-top:1px solid #f6f6f6;} .bor-l{ border-left:1px solid #f6f6f6;} .bor-b{ border-bottom:1px solid #f6f6f6;} .bor-r{ border-right:1px solid #f6f6f6;} .w100{ width: 100%; } .bor-ra10{ border-radius:10rpx; } .bor-ra20{ border-radius:10rpx; } .bor-ra30{ border-radius:10rpx; } .bor-ra40{ border-radius:10rpx; } .bor-ra50{ border-radius:10rpx; } .line{ width: 100%; height: 1px; background: #f3f3f3; clear: both;} .nobor{ border: none;} .jszc{ margin-top: 80rpx; color: #999999;} /** 位置 */ .f-l{ float: left;} .f-c{ margin: 0 auto; float:initial;} .f-r{ float: right;} .po-r { position: relative;} .po-a { position: absolute;} .po-f { position: fixed;} .po-ft { position: fixed; top: 0px;left: 0px;} .po-fb { position: fixed; bottom: 0px; left: 0px;} .m0{margin: 0rpx;} .m10{ margin: 10rpx; } .m20{ margin: 20rpx; } .m30{ margin: 30rpx; } .m40{ margin: 40rpx; } .mt0{margin-top: 0rpx;} .mt10{ margin-top: 10rpx;} .mt20{margin-top: 20rpx;} .mt30{margin-top: 30rpx;} .ml0{margin-left: 0rpx;} .ml10{margin-left: 10rpx;} .ml20{margin-left: 20rpx;} .mr0{margin-right: 0rpx;} .mr10{margin-right: 10rpx;} .mr20{margin-right: 20rpx;} .mb0{margin-bottom: 0rpx;} .mb10{margin-bottom: 10rpx;} .mb20{margin-bottom: 20rpx;} .mb30{margin-bottom: 30rpx;} .m020{margin:0 20rpx;} .p0{ padding: 0rpx; } .p10{ padding: 10rpx; } .p20{ padding: 20rpx; } .p30{ padding: 30rpx; } .pt0{padding-top: 0rpx;} .pt10{padding-top: 10rpx;} .pt20{padding-top: 20rpx;} .pl0{padding-left: 0rpx;} .pl10{padding-left: 10rpx;} .pl20{padding-left: 20rpx;} .pr0{padding-right: 0rpx;} .pr10{padding-right: 10rpx;} .pr20{padding-right: 20rpx;} .pb0{padding-bottom: 0rpx;} .pb10{padding-bottom: 10rpx;} .pb20{padding-bottom: 20rpx;} .p010{padding:0 10rpx;} .p020{padding:0 20rpx;} .p030{padding:0 30rpx;} .bg-sub{ background: #7479f6;} .all-tip{ height: 80rpx; padding: 0 30rpx; color: #3f3f3f; line-height: 80rpx; overflow: hidden; background: #f0e4c1;} .hide{ display: none; opacity: 0;} .show{ display: block; opacity: 1;} .line-30{line-height: 30rpx;} .line-40{line-height: 40rpx;} .line-50{line-height: 50rpx;} .line-60{line-height: 60rpx;} .line-70{line-height: 70rpx;} .line-80{line-height: 80rpx;} .line-90{line-height: 90rpx;} .line-100{line-height: 100rpx;} .h-30{height: 30rpx; overflow: hidden;} .h-40{height: 40rpx; overflow: hidden;} .h-50{height: 50rpx; overflow: hidden;} .h-60{height: 60rpx; overflow: hidden;} .h-70{height: 70rpx; overflow: hidden;} .h-80{height: 80rpx; overflow: hidden;} .h-90{height: 90rpx; overflow: hidden;} .h-100{height: 100rpx; overflow: hidden;} .h-120{height: 120rpx; overflow: hidden;} .h-140{height: 140rpx; overflow: hidden;} .h-160{height: 160rpx; overflow: hidden;} .h-180{height: 180rpx; overflow: hidden;} .h-200{height: 200rpx; overflow: hidden;} .ovh{ overflow: hidden;} /** 字体 */ .t-c{ text-align: center;} .t-l{ text-align: left;} .t-r{ text-align: right;} .f-18{ font-size: 18rpx;} .f-24{ font-size: 24rpx;} .f-26{ font-size: 26rpx;} .f-28{ font-size: 28rpx;} .f-30{ font-size: 30rpx;} .f-32{ font-size: 32rpx;} .f-34{ font-size: 34rpx;} .f-36{ font-size: 34rpx;} .f-38{ font-size: 34rpx;} .f-40{ font-size: 40rpx;} .f-45{ font-size: 45rpx;} .f-50{ font-size: 50rpx;} .f-55{ font-size: 55rpx;} .f-60{ font-size: 60rpx;} .ellipsis { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; display: block;} .bold{ font-weight: bold;} /** 字体颜色 */ .co-r{ color: #ee2b2b;} .price{ color: #ff0000;} .co-w{ color: #ffffff;} .co-o{ color: #ff9000} .co-g{ color:green;} .co-y{ color: #fbd051} .co-0{ color: #000000;} .co-3{ color: #333333;} .co-6{ color: #666666;} .co-9{ color: #999999;} .co-gray{color: #7f8699} .ico1{ color:#ff1260;} .ico2{ color:#fa741b;} .ico3{ color:#7a67ff;} .ico4{ color:#2cba80;} .ico5{ color:#7479f6;} .ico7{ color:#ff9018;} /** 按钮 */ .btn96{ height: 80rpx; line-height: 80rpx;font-size: 40rpx; background: #ec4e43; color: #ffffff; text-align:center; margin:40rpx auto;} .btn96{ width:96%;} .btn100{ width:100%;} .btn-bottom{position: fixed; bottom: 0px; left: 0px; background: #7479f6; font-size: 36rpx; text-align: center;color: #ffffff; height: 80rpx; line-height: 80rpx;border-radius: 0px; width: 100%; } .btn-sub{ border: 1px solid #999999; font-size: 28rpx; text-align: center; border-radius: 10rpx; padding: 5rpx 20rpx; color: #999999; margin: 0 auto; display: block; line-height: 50rpx; height: 50rpx; } /** 栅格布局 */ .row { display: block; margin: 0px;} .col { display: flex; font-family: -apple-system-font, "Helvetica Neue", sans-serif; font-size: 30rpx;} .col>.col-1,.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9,.col-10, .col-11, .col-12 { overflow: hidden;float: left;} .col-1 { width: 8.33333333333333%;} .col-2 { width: 16.6666666666666%;} .col-3 { width: 25%;} .col-4 { width: 33.3333333333333%;} .col-5 { width: 41.6666666666666%;} .col-6 { width: 50%;} .col-7 { width: 58.333333333333333%;} .col-8 { width: 66.66666666666666%;} .col-9 { width: 75%;} .col-10 { width: 83.33333333333333%;} .col-11 { width: 91.66666666666666%;} .col-12 { width: 100%;} .img40{ width: 80rpx; height: 80rpx;} .img60{ width: 120rpx; height: 120rpx;} .img80{ width: 160rpx; height: 160rpx;} .img100{ width: 200rpx; height: 200rpx;} .z-99{ z-index: 99;} .navigator-hover { opacity: 1; background: none;} .kongbai{ height: 100rpx; width: 100%; overflow: hidden;}
小程序DOM使用如下:
3、VIEW的部分源码展示
<view class="container"> <!--轮播图 GO--> <view class="swiper-box ovh po-r index-banner"> <swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for='{{banner}}' wx:key="index"> <swiper-item data-index='{{index}}'> <navigator url="{{item.url}}" hover-class="navigator-hover"> <image src="{{item.img_src}}" class="slide-image" width="355" height="200" /> </navigator> </swiper-item> </block> </swiper> </view> <!--轮播图 END--> <!--功能图标 GO--> <view class='menu bg-w ovh css3' wx:if="{{nav}}"> <view class='items'> <view class="item po-r" wx:for="{{nav}}" wx:key="index"> <navigator open-type='switchTab' url='{{item.url}}' wx:if="{{item.url=='/pages/index/index' || item.url=='/pages/user/course-res' || item.url=='/pages/user/index' }}"> <image class="fiximg" src="{{item.img_src}}"></image> <text class='co-3 f-30 t-c dis-b'>{{item.title}}</text> </navigator> <navigator url='{{item.url}}' wx:else> <image class="fiximg" src="{{item.img_src}}"></image> <text class='co-3 f-30 t-c dis-b'>{{item.title}}</text> </navigator> </view> </view> </view> <!--功能图标 END--> <view class='navbg ovh'> <text class='title line-80 t-c f-l p020 bold'>全部课程</text> <icon class='line-80 t-c f-r p020 iconfont iconquanbu' bindtap="showviewfc"></icon> </view> <!--按周显示课程 GO--> <block wx:if="{{curriculum}}"> <view class="menu1 line-80 bg-w ovh"> <text bindtap="tab" data-type="1" class="{{startweek==1 ? 'active' : ''}}">周一</text> <text bindtap="tab" data-type="2" class=" {{startweek==2 ? 'active' : ''}}">周二</text> <text bindtap="tab" data-type="3" class=" {{startweek==3 ? 'active' : ''}}">周三</text> <text bindtap="tab" data-type="4" class=" {{startweek==4 ? 'active' : ''}}">周四</text> <text bindtap="tab" data-type="5" class=" {{startweek==5 ? 'active' : ''}}">周五</text> <text bindtap="tab" data-type="6" class=" {{startweek==6 ? 'active' : ''}}">周六</text> <text bindtap="tab" data-type="7" class=" {{startweek==7 ? 'active' : ''}}">周日</text> </view> <!--课程列表 GO--> <view class='p30 bg-w ovh m-nav pr0'> <view class='item po-r ovh' wx:key="key" wx:for="{{curriculum}}"> <navigator class='dis-ib' url='/pages/course/detial-list?id={{item.id}}'> <form bindsubmit='submit' report-submit='true' data-type="submit"> <image mode="aspectFill" class='f-l mt20' src='{{item.coach.avatar}}'></image> <view class='wrap'> <view class='first pl20 line-40 h-40 f-32 ellipsis t-l'>{{item.title}}</view> <view class='cont pl20 f-28 ellipsis t-l co-9'>教师:{{item.coach.nickname}}</view> <view class='cont pl20 f-28 ellipsis t-l co-9'>履历:{{item.coach.bio}}</view> <view class='cont pl20 f-28 ellipsis t-l co-9'>时间:{{item.starttime}}</view> <view class='cont pl20 f-28 ellipsis t-l co-9'>地点:{{item.address}}</view> </view> </form> </navigator> </view> </view> </block> <!--课程列表 GO--> <block> <view class='p30 bg-w ovh pb0 mt30'> <text class='f-l co-3'>推荐课程</text> <navigator url='/pages/course/list' class='dis-ib f-r'> <text class='f-r ico7 f-24'>查看更多</text> </navigator> </view> <view class='p30 bg-w ovh m-children t-c'> <image mode='aspectFit' src='../../images/child.png'></image> </view> </block> <!-- 底线 --> <view class="title-footer p-r"> <text class="f-24 co-9 cont t-c">已经到底啦</text> <view class="hr"></view> </view> <!-- 返回顶部 --> <view bindtap="goTop" class="widget-goTop" wx:if="{{floorstatus}}"> <text class="iconfont icon-fanhuidingbu"></text> </view> <!--课程分类弹窗--> <view class='searbox po-f ovh bg-w css3 {{showview?"scrolll":"scrollr"}}'> <view class='po-r ovh p20'> <text class='f-r co-9 po-a close' bindtap='showhide'>关闭</text> <scroll-view class="scroll-view_H t-c" scroll-y style="width: 100%; height:94vh;padding-top:6vh;" catchtouchmove="true"> <view class='seccat ovh p020 mb10 dis-ib co-9' bindtap='changeid' data-id='' wx:key="{{key}}">全部</view> <view class='seccat ovh p020 mb10 dis-ib co-9' wx:for="{{catelist}}" bindtap='changeid' data-id='{{item.id}}' wx:key="index">{{item.name}}</view> </scroll-view> </view> </view> </view>
view展示注意点:
1、在小程序开发工具中,不影响运行,但是要呈现演示数据,需要js中把api的变量定义成静态数据。
2、页面中学生端和教师端是通过判断用户的教师id来区分展示对应身份的界面,所以部分涉及身份的页面是连段代码,谨记。
4、JS首页完整代码展示
let App = getApp(); Page({ data: { // banner轮播组件属性 indicatorDots: true, // 是否显示面板指示点 autoplay: true, // 是否自动切换 interval: 3000, // 自动切换时间间隔 duration: 800, // 滑动动画时长 imgHeights: {}, // 图片的高度 imgCurrent: {}, // 当前banne所在滑块指针 show: false, showview: false, items: {}, category_id: '', startweek: 1, startPoint: '' }, onLoad: function() { // 设置页面标题 App.setTitle(); // 获取首页数据 this.getHomeData(); this.getCategorylist(); this.getIndexCurriculum(); }, onShow: function() { this.onLoad(); }, /** * 获取首页数据 */ getHomeData: function() { let that = this; App._get('index/index', {}, function(res) { that.setData(res.data); }); }, /** * 课程分类列表 */ getCategorylist: function() { let that = this; App._get('index/curriculumCategorylist', {}, function(result) { that.setData({ catelist: result.data }); }); }, /** * 获取分类id */ changeid: function(e) { let that = this; var category_id = e.currentTarget.dataset.id; that.setData({ category_id: category_id }); that.getIndexCurriculum(); that.showhide(); }, //触发分类弹窗 showviewfc: function () { var that = this; that.setData({ showview: true }) }, //关闭分类弹窗 showhide: function () { var that = this; that.setData({ showview: false }) }, /** * 获取 首页课程数据 */ getIndexCurriculum: function() { let that = this; App._get('index/curriculumlist', { startweek: that.data.startweek, category_id: that.data.category_id }, function(result) { that.setData(result.data); }); }, //周别切换 tab: function(e) { var startweek = e.currentTarget.dataset.type; this.setData({ startweek: startweek }); this.getIndexCurriculum(); }, /** * 计算图片高度 */ imagesHeight: function(e) { let imgId = e.target.dataset.id, itemKey = e.target.dataset.itemKey, ratio = e.detail.width / e.detail.height, // 宽高比 viewHeight = 750 / ratio, // 计算的高度值 imgHeights = this.data.imgHeights; // 把每一张图片的对应的高度记录到数组里 if (typeof imgHeights[itemKey] === 'undefined') { imgHeights[itemKey] = {}; } imgHeights[itemKey][imgId] = viewHeight; // 第一种方式 let imgCurrent = this.data.imgCurrent; if (typeof imgCurrent[itemKey] === 'undefined') { imgCurrent[itemKey] = Object.keys(this.data.items[itemKey].data)[0]; } this.setData({ imgHeights, imgCurrent }); }, //首页分享 onShareAppMessage: function() { return { title: "小程序首页", desc: "", path: "/pages/index/index" }; }, /* *下拉显示 */ onPullDownRefresh() { var that = this; that.setData({ show: true }) }, /** * 页面上拉触底事件的处理函数 */ move: function(e) { var curPoint = [e.touches[0].pageX, e.touches[0].pageY]; var starPoint = this.data.startPoint; that.setData({ show: false }) }, });
5、教师端界面截图
最后:
如果需要了解体验小程序后台及api、数据库可通过平台联系我。
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码