很是感謝那些無私開源的程序員,但願我也可以有能力像大家那樣,開源不少頗有意思的東西~~css
//index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0"> <title>fitness-app</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
//App.vue <template> <div class="app" style="height:100%;"> <router-view></router-view> </div> </template> <script> export default { name: 'app' } </script> <style lang="less"> @import '~vux/src/styles/reset.less'; body { background-color: #fbf9fe; } </style>
//main.js // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import FastClick from 'fastclick' import VueRouter from 'vue-router' import App from './App' import router from'./router/memberRouter.js' //---------自定義的路由文件 import Base from './assets/js/baseFun.js' //---------自定義的公共函數和公共請求方法 import stores from './store/store' //---------自定義的全局變量 import './assets/css/base.css' //---------引入的全局公共css FastClick.attach(document.body) Vue.config.productionTip = false //註冊全局函數和全局常量 Vue.prototype.baseFun=Base.baseFun; //-----註冊到vue的全局,方便各個組件和頁面js調用公共函數 Vue.prototype.baseAjax=Base.baseAjax;//-----將封裝的ajax請求函數註冊到vue的全局 Vue.use(VueRouter) var globalVm=new Vue({ router, //-----router文件 el: '#app', store:stores, //-----全局變量 template: '<App/>', components: { App } })
//memberRouter.js路由 import Vue from 'vue' import VueRouter from 'vue-router' import memberHome from '@/components/memberHome' import activityIndex from '@/components/member/activities/activityIndex' import activityDetail from '@/components/member/activities/activityDetail' import groupCourses from '@/components/member/groupCourses/groupCourses' import personalCourses from '@/components/member/personalCourses/personalCourses' import personalCourseDetail from '@/components/member/personalCourses/personalCourseDetail' import mine from '@/components/member/mine/mine' Vue.use(VueRouter) const router = new VueRouter({ mode: 'hash', base: __dirname, //路由映射map routes: [ { path: '/', redirect: '/memberHome/activityIndex' }, { path: '*', redirect: '/memberHome/activityIndex' }, { path: '/memberHome', name: 'memberHome', component: memberHome, children:[ { path: '/memberHome/activityIndex', name: 'activityIndex', component: activityIndex }, { path: '/memberHome/activityDetail/:activityId', name: 'activityDetail', component: activityDetail }, { path: '/memberHome/groupCourses', name: 'groupCourses', component: groupCourses }, { path: '/memberHome/mine', name: 'mine', component: mine }, { path: '/memberHome/personalCourses', name: 'personalCourses', component: personalCourses }, { path: '/memberHome/personalCourseDetail/:courseId/:date', name: 'personalCourseDetail', component: personalCourseDetail } ] }, ] }); export default router;
固定頭部和下部
html
//memberHome.vue <template> <div class="memberHome" style="height: 100%"> <view-box ref="viewbox" body-padding-top="46px"> <div class="vux-demo-header-box" slot="header"> <!-- 插槽過來的變更的頭部 --> <x-header :left-options="{backText: ''}" v-show="headShow">{{pageTitle}}</x-header> </div> <div v-transfer-dom class="loading-box"> <loading :show="loading" position="absolute"></loading> </div> <!-- 中間部分固定 --> <router-view></router-view> <!-- 下部是固定部分 --> <tabbar v-show="footerShow"> <tabbar-item selected link="/memberHome/newsIndex"> <img slot="icon" src="../assets/images/icons/news_icon.png"> <span slot="label">最新活動</span> </tabbar-item> <tabbar-item link="/memberHome/groupCourses"> <img slot="icon" src="../assets/images/icons/group_icon.png"> <span slot="label">團體課</span> </tabbar-item> <tabbar-item link="/memberHome/personalCourses"> <img slot="icon" src="../assets/images/icons/private_icon.png"> <span slot="label">私教課</span> </tabbar-item> <tabbar-item link="/memberHome/mine"> <img slot="icon" src="../assets/images/icons/mine_icon.png"> <span slot="label">個人</span> </tabbar-item> </tabbar> </view-box> </div> </template> <script> import { Tabbar,Icon,TabbarItem ,XHeader,Loading,ViewBox} from 'vux' import { TransferDomDirective as TransferDom } from 'vux' import {mapGetters} from 'vuex' export default { computed:mapGetters([ 'headShow', 'loading', 'footerShow', 'pageTitle' ]), data(){ let data={ } return data }, mounted() { }, directives: { TransferDom }, components: { Tabbar, TabbarItem, XHeader, Loading, ViewBox, Icon } } </script> <style> .memberHome .vux-demo-header-box { z-index: 100; position: absolute; width: 100%; left: 0; top: 0; } .memberHome .weui-tabbar__icon img{ width: auto; height: 90%; } .memberHome .weui-tabbar__item.weui-bar__item_on .weui-tabbar__label{ color: #DD5858 } </style>
store中是存儲狀態的vue
//store.js import Vue from 'vue' import Vuex from 'vuex' import mutations from './mutations' import actions from './actions' Vue.use(Vuex); export default new Vuex.Store({ modules:{ mutations }, actions });
//data.js至關於state //是否顯示頭部 export const UPDATE_HEAD='UPDATE_HEAD'; //是否顯示loading export const UPDATE_LOADING='UPDATE_LOADING'; //是否顯示footer export const UPDATE_FOOTER='UPDATE_FOOTER'; //頁面標題 export const UPDATE_PAGE_TITLE='UPDATE_PAGE_TITLE';
//action.js //import 數據 from '' 這裏面能夠獲取數據 import * as data from './data' export default{ UPDATE_HEAD:({commit})=>{ commit(data.UPDATE_HEAD); }, UPDATE_LOADING:({commit})=>{ commit(data.UPDATE_LOADING); }, UPDATE_FOOTER:({commit})=>{ commit(data.UPDATE_FOOTER) }, UPDATE_PAGE_TITLE:({commit})=>{ commit(data.UPDATE_PAGE_TITLE) } }
//mutations.js import { UPDATE_HEAD, UPDATE_LOADING, UPDATE_FOOTER, UPDATE_PAGE_TITLE } from './data' const state={ headShow:true, loading:false, footerShow:true, pageTitle:'首頁' }; const mutations={ /*head*/ [UPDATE_HEAD](state,type){ state.headShow=type; }, /*loading*/ [UPDATE_LOADING](state,type){ state.loading=type; }, /*footer*/ [UPDATE_FOOTER](state,type){ state.footerShow=type; }, /*title*/ [UPDATE_PAGE_TITLE](state,type){ state.pageTitle=type; } }; const getters={ headShow(state){ return state.headShow; }, loading(state){ return state.loading; }, footerShow(state){ return state.footerShow; }, pageTitle(state){ return state.pageTitle; } }; export default{ state, mutations, getters }
//activityIndex.vue <template> <div class="activityIndex page"> <div class="activeItem" v-for="item in itemList"> <router-link :to="'/memberHome/activityDetail/'+item.id"> <div class="newsImg"> <img src="../../../assets/images/news-img.png"/> </div> <div class='sbottom'> <p class="title">{{item.title}}</p> <p class="time-line"><span class='time'>{{item.startDate}} - {{item.endDate}}</span> <span class="view"><span class="view_icon"><img src="../../../assets/images/icons/view.png"></span>{{item.viewer || 0}}人</span></p> </div> </router-link> </div> </div> </template> <script> import { Tabbar, TabbarItem ,XHeader,XButton,XImg} from 'vux' export default { mounted() { this.loadLatest(); //插入頭部 this.$store.commit('UPDATE_PAGE_TITLE', '最新活動') }, data(){ return { itemList:'' } }, methods:{ loadLatest(){ //從後端取數據 let self=this; this.baseAjax({ url:'../../../static/basicData/latestActivity.json', showLoading:true, success:function(data){ console.log(data) self.itemList=data.returnObject } }) } }, components: { Tabbar, TabbarItem, XHeader, XButton, XImg } } </script> <style> .activityIndex .activeItem{ margin:10px 10px 0 10px; position: relative; height: 180px; overflow: hidden; border-radius: 5px } .activityIndex .activeItem .sbottom{ color: white; position: absolute; bottom: 10px; padding: 10px; width: 85%; }s .activityIndex .activeItem .title{ font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .activityIndex .time-line{ font-size: 14px; width: 100%; height: 20px; } .activityIndex .activeItem .view{ float: right; font-size: 14px; } .activityIndex .activeItem .newsImg img{ width: 100%; min-height: 180px; } .activityIndex .sbottom img{ width: 16px; height: 12px; padding-right: 5px; } </style>
//activityDetail.vue <template> <div class="activityDetail"> <div class="newsImg"> <img src="../../../assets/images/news-img.png"/> </div> <div class="detail-box"> <div class="text-top"> <p class="title">{{mainData.title}}</p> <div class="sDate"> <flexbox> <flexbox-item>發佈時間:{{mainData.publishDate}}</flexbox-item> <flexbox-item>瀏覽量:{{mainData.viewer}}</flexbox-item> </flexbox> </div> </div> <div class="detail-text"> <p v-html="mainData.content"> {{mainData.content}} </p> </div> </div> </div> </template> <script> import {Flexbox, FlexboxItem,XImg} from 'vux' export default{ mounted() { this.loadDetail(); this.$store.commit('UPDATE_PAGE_TITLE', '活動詳情'); }, data(){ return { mainData:'' } }, methods:{ loadDetail(){ let self=this; let id=this.$route.params.activityId; this.baseAjax({ url:'../../../static/basicData/activityDetail.json', showLoading:true, success:function(data){ console.log('data.returnObject',data.returnObject) self.mainData=data.returnObject } }) } }, components:{ Flexbox, FlexboxItem,XImg } } </script> <style> .activityDetail .newsImg{ height:180px; overflow: hidden; } .activityDetail .title{ font-size: 16px; line-height: 22px; } .activityDetail .detail-text{ color: #666; padding:10px 15px; } .activityDetail .detail-text p{ text-indent: 28px; font-size: 14px; line-height: 22px; color: #666 } .activityDetail .newsImg img{ width: 100%; min-height: 180px; } .activityDetail .sDate{ margin-top: 10px; font-size: 12px; color: #666 } .activityDetail .text-top{ border-bottom: 1px solid #eee; padding: 10px 15px 15px 15px; } </style>
//mine.vue <template> <div clas="mine"> <h1>個人課程</h1> </div> </template>
//personalCourses.js //封裝的日期組件 import { Tab, TabItem,XImg,dateFormat,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup} from 'vux'; let cnM=['一','二','三','四','五','六','七','八','九','十','十一','十二']; // 獲取一週的日期 // 獲取當前星期的星期一的日期,返回的是一個Date對象。 function getMonDate(dd){ //config爲日期 例如:2016-04-19 let d=new Date(dd); let day=d.getDay(); let date=d.getDate(); if(day==1) return d; if(day==0) d.setDate(date-6); else d.setDate(date-day+1); return d; } //獲取一週的日期; function getWeekDate(self,confg){ let d=getMonDate(confg); let wkd=new Date(confg).getDay(); self.selectIndex=wkd==0?6:wkd-1 for(var i=0;i<7;i++){ self.dateList[i].date = d.getDate(); self.dateList[i].configDate=dateFormat(new Date(d), 'YYYY-MM-DD'); d.setDate(d.getDate()+1); } } export default { mounted() { this.$store.commit('UPDATE_PAGE_TITLE', '私教課') getWeekDate(this,this.myd); //加載一週數據 this.loadCourses(); //加載課程列表 }, data(){ let self=this; let data={ calendarDate:"", dateList :[ {week:'週一',date:'',configDate:'',limit:false}, {week:'週二',date:'',configDate:'',limit:false}, {week:'週三',date:'',configDate:'',limit:false}, {week:'週四',date:'',configDate:'',limit:false}, {week:'週五',date:'',configDate:'',limit:false}, {week:'週六',date:'',configDate:'',limit:false}, {week:'週日',date:'',configDate:'',limit:false} ], myd:dateFormat(new Date(), 'YYYY-MM-DD'), pickMonth:cnM[new Date().getMonth()], pickDate:new Date().getDate(), selectIndex:null, courseList:'', showCalendar:false, weeksList:['日','一','二','三','四','五','六'], coursesQueryData:{ date:dateFormat(new Date(), 'YYYY-MM-DD'), } } return data }, methods:{ // 獲取團體課列表 loadCourses(){ let self=this; //與後端交互請求後端數據 this.baseAjax({ url:'../../../static/basicData/personalCourse.json', params:{ date:self.coursesQueryData.date }, showLoading:true, success:function(data){ console.log(data) self.courseList=data.returnObject; } }) }, //選擇日期 calendarChange(date){ if(date==this.coursesQueryData.date) return; getWeekDate(this,date); this.coursesQueryData.date=date; this.showCalendar=false; this.loadCourses(); }, //日期點擊事件 dateHandler(idx){ this.selectIndex=idx; this.coursesQueryData.date=this.dateList[idx].configDate; this.loadCourses(); }, //打開日期控件 openCalendar(){ this.showCalendar=true; } }, components: { Tab,TabItem,XImg,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup } }
//src/components/member/personalCourses/personalCourses.vue <template> <div class="personalCourses"> <div class="topDate"> <tab :animate=false :line-width="1"> <tab-item disabled> <div class='left-calendar' @click="openCalendar()" > <p class="pickDate">{{pickDate}}</p> <p class="pickMonth">{{pickMonth}}月</p> </div> </tab-item> <tab-item @on-item-click="dateHandler(index)" v-for="(date,index) in dateList" :key="index" v-bind:class="{'vux-tab-selected': index==selectIndex ,'vux-tab-notSelected': index!=selectIndex}"> <p>{{date.week}}</p> <p>{{date.date}}</p> </tab-item> </tab> </div> <div class="classItems"> <div class="item-box" v-for="(item,index) in courseList" :key="index"> <flexbox> <flexbox-item :span="3"> <div class="item-icon"> <img src="../../../assets/images/timg.png"/> </div> </flexbox-item> <flexbox-item> <div class="top-name"> <flexbox> <flexbox-item> <div>{{item.name}}</div> <p class="item-desc">{{item.description}}</p> </flexbox-item> <flexbox-item :span="4"> <router-link :to="'/memberHome/personalCourseDetail/'+item.id+'/'+coursesQueryData.date" v-show="item.status==1" > <x-button mini type="warn" action-type='button' >預定</x-button> </router-link> <x-button mini type="default" v-show="item.status==2" action-type='button' >已預定</x-button> </flexbox-item> </flexbox> </div> <div class="bottom-cer"> <span>{{item.certification}}</span> </div> </flexbox-item> </flexbox> </div> </div> <div> <popup v-model="showCalendar"> <inline-calendar @on-change="calendarChange" class="my-inline-calendar" v-model="calendarDate" :weeks-list="weeksList" > </inline-calendar> </popup> </div> </div> </template> <script> import personalCourses from "./js/personalCourses.js" export default personalCourses </script> <style> .personalCourses .vux-tab .vux-tab-item{ line-height: 20px; } .personalCourses .pickDate { color:#DD5858; font-size: 16px; } .personalCourses .classItems{ margin-top: 60px; } .personalCourses .left-calendar{ margin-left:5px; border-radius: 5px; background: #eee; } .personalCourses .vux-tab{ height: 46px } .personalCourses .activeItem img{ width: 100% } .personalCourses .activeItem{ margin:10px 10px 0 10px; position: relative; height: 180px; overflow: hidden; border-radius: 5px } .personalCourses .topDate{ position: absolute; top: 52px; z-index: 10; width: 100%; } .personalCourses .activeItem .sbottom{ color: white; position: absolute; bottom: 10px; padding:10px; width: 85% } .personalCourses .activeItem .title{ font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .personalCourses .time-line{ font-size: 14px; width: 100%; height: 20px; } .personalCourses .activeItem .view{ float: right; font-size: 14px; } .personalCourses .activeItem img{ width: 100% } .personalCourses .vux-tab .vux-tab-item.vux-tab-disabled { color: #666; } .personalCourses .vux-tab .vux-tab-item.vux-tab-selected{ color:#DD5858; border-width: 3px !important; border-bottom: 3px solid #DD5858; } .personalCourses .vux-tab .vux-tab-item.vux-tab-notSelected{ border-bottom:1px solid #eee; color: #666 } .personalCourses .inline-calendar td.current > span.vux-calendar-each-date { background-color: #DD5858; } .personalCourses .inline-calendar td.is-today{ color:#DD5858; } .personalCourses .item-box .item-icon{ height: 60px; text-align: center; overflow: hidden; } .personalCourses .item-box .item-icon img{ height: 100%; border-radius: 50% } .personalCourses .item-box { border-bottom:1px solid #eee; background: #fff; } .personalCourses .top-name{ border-bottom:1px solid #eee; padding: 10px 0; margin-right: 10px; } .personalCourses .item-desc{ font-size:12px; line-height: 20px; color: #666 } .personalCourses .bottom-cer{ padding:10px 0; font-size:12px; color: #666 } .personalCourses .bottom-cer span{ padding: 5px; border-radius: 5px; background: #eee; margin: 5px; } .personalCourses button.weui-btn_mini{ width: 65px; padding: 0; } </style>
//personalCourseDetail.vue <template> <div class="personalCourseDetail"> <div class="top-box"> <flexbox> <flexbox-item :span="3"> <div class="item-icon"> <img src="../../../assets/images/timg.png"/> </div> </flexbox-item> <flexbox-item> <div class="top-name"> <div class="s-name"><span>{{mainData.name}}</span><span class="name-label">私教</span></div> <p class="item-desc">{{mainData.description}}</p> </div> <div class="bottom-cer"> <x-icon type="ios-clock-outline" size="20" class="icon-clock"></x-icon> <p><span>{{currentDate}}</span><span>({{currentDay}})</span></p> </div> </flexbox-item> </flexbox> </div> <div> <p class="remark">上課時間(時長:1小時)</p> </div> <div class="time-box"> <div v-for="(item,index) in timeList" class="time-item" :key="index"> <div class="group-head" @click="item.showList=!item.showList"> <flexbox> <flexbox-item :span="2"> <div v-show="index==0" class="s-icon"><x-icon type="ios-partlysunny-outline" size="30"></x-icon></div> <div v-show="index==1" class="s-icon"><x-icon type="ios-sunny-outline" size="30"></x-icon></div> <div v-show="index==2" class="s-icon"><x-icon type="ios-moon-outline" size="30"></x-icon></div> </flexbox-item> <flexbox-item ><div>{{item.name}}</div></flexbox-item> <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item> </flexbox> </div> <div class="list-box" v-show="item.showList"> <div class="checker-box"> <checker v-model="checkTime" type="checkbox" default-item-class="checkTime-item" selected-item-class="checkTime-item-selected" disabled-item-class="checkTime-item-disabled" > <checker-item v-for="(sitem,sindex) in item.list" :key="sindex" :value="sitem.time" :disabled="!sitem.isEnable" @on-item-click="checkMyTime(index,sitem.time,sitem.isEnable)">{{sitem.time}} </checker-item> </checker> </div> </div> </div> <div class="labels"> <div class="is-allow">可選</div> <div class="no-allow">不可選</div> <div class="is-select">已選擇</div> </div> <div class="bottom-btn" v-show="showReserveBtn"> <x-button type="warn" @click.native="makeReserve">肯定預定</x-button> </div> </div> <toast v-model="showSuccess" type="text" class="showSuccess" :time="2000">預定成功</toast> <toast v-model="showError" type="text" class="showError" :time="2000">預定失敗</toast> <toast v-model="showMsg" type="text" class="showMsg" :time="2000">請選擇1h相鄰的時間段</toast> </div> </template> <script> import personalCourseDetail from "./js/personalCourseDetail.js" export default personalCourseDetail </script> <style> .personalCourseDetail .top-box{ background: #fff } .personalCourseDetail .item-icon{ height: 60px; text-align: center; overflow: hidden; } .personalCourseDetail .item-icon img{ height: 100%; border-radius: 50% } .personalCourseDetail .item-box { border-bottom:1px solid #eee; background: #fff; } .personalCourseDetail .top-name{ border-bottom:1px solid #eee; padding: 10px 0 5px 0; margin-right: 10px; } .personalCourseDetail .item-desc{ font-size:12px; line-height: 20px; color: #666; clear:both; } .personalCourseDetail .bottom-cer{ padding:10px 0; font-size:12px; color: #666; position :relative; } .personalCourseDetail .bottom-cer p{ padding-left: 15px; line-height: 20px; } .personalCourseDetail .bottom-cer p span{ padding-left: 10px } .personalCourseDetail .icon-clock{ position:absolute; fill: #666; } .personalCourseDetail .s-icon{ padding-left: 20px } .personalCourseDetail .group-head{ font-size: 14px; padding-top: 5px; border-bottom: 1px solid #eee } .personalCourseDetail .remark{ height: 40px; font-size: 14px; line-height: 40px; color: #666; padding-left: 20px } .personalCourseDetail .time-box{ background: #fff; padding-bottom:10px ; } .personalCourseDetail .checker-box{ margin:15px; } .personalCourseDetail .time-item{ border-bottom: 1px solid #eee } .personalCourseDetail .arrow-icon{ text-align: right; padding-right: 15px; } .personalCourseDetail .checkTime-item { width: 20%; height: 32px; line-height: 32px; text-align: center; border: 1px solid #ccc; background-color: #fff; color: #000; box-sizing: border-box; } .personalCourseDetail .checkTime-item-selected { background: #333333 url(../../../assets/images/bgIcon/select-icon.png) no-repeat right bottom; background-size:12px 10px; color: #fff; border: 1px solid #333333; border-right:1px solid #ccc; } .personalCourseDetail .checkTime-item-disabled{ background: #DEDCDC; } .personalCourseDetail .bottom-btn{ padding:20px; } .personalCourseDetail .labels{ margin:5px 30px; height: 30px; line-height: 30px } .personalCourseDetail .labels >div{ float:left; margin-right: 20px; font-size: 12px; padding-left: 20px; } .personalCourseDetail .labels .is-allow{ background: url(../../../assets/images/bgIcon/is-allow.png) no-repeat left center ; background-size:12px; } .personalCourseDetail .labels .no-allow{ background: url(../../../assets/images/bgIcon/no-allow.png) no-repeat left center ; background-size:12px; } .personalCourseDetail .labels .is-select{ background: url(../../../assets/images/bgIcon/is-select.png) no-repeat left center ; background-size:12px; } .personalCourseDetail .s-name span{ height:30px; line-height: 30px; display:block; float: left; } .personalCourseDetail .s-name .name-label{ background: #6B106A; color: #fff; font-size: 12px; height:20px; line-height: 20px; margin: 5px 10px; padding:0 10px; } .personalCourseDetail .showSuccess .weui-toast__content{ background: url(../../../assets/images/bgIcon/success.png) no-repeat left center ; background-size:20px; } .personalCourseDetail .showSuccess .weui-toast{ padding-left: 10px; } </style>
//personalCourseDetail.js import { XImg,XButton,Flexbox, FlexboxItem,XDialog,Checker, CheckerItem,Toast} from 'vux'; export default { mounted(){ this.loadDetail(); this.$store.commit('UPDATE_PAGE_TITLE', '課程預定'); }, computed:{ currentDay(){ let date=this.$route.params.date; let day=new Date(date).getDay(); let cnM=['日','一','二','三','四','五','六']; return "周"+cnM[day] } }, data(){ let self=this; let data={ mainData:{}, showSuccess:false, showError:false, showMsg:false, currentDate:self.$route.params.date, checkTime:[], activeType:0, timeListArr:[[],[],[]], showReserveBtn:true, timeList:[ {name:"上午", list:[], showList:false }, {name:"下午", list:[], showList:false }, {name:"晚上", list:[], showList:false } ] } return data; }, methods:{ // 獲取詳細信息 loadDetail(){ let self=this; let courseId=this.$route.params.courseId; let date=this.$route.params.date; this.baseAjax({ url:'../../../static/basicData/personalDetail.json', showLoading:true, params:{ courseId:courseId, date:date }, success:function(data){ self.mainData=data.returnObject[0]; //從後端請求的~~不一樣人的數據不一樣 self.computeTimeLost(self.mainData.scheduleTime) } }) }, // 計算時間列表 computeTimeLost(list){ let self=this; let len=list.length; for(let i=0;i<len;i++){ let type=list[i].type-1; list[i].check=false; self.timeList[type].list.push(list[i]); self.timeListArr[type].push(list[i].time); } console.log(self.timeList) }, //選中時間 checkMyTime(idx,val,isEnable){ if(!isEnable) return; if(this.activeType!=idx){ this.checkTime=[val]; this.activeType=idx } console.log(this.checkTime) }, //預約私教課 makeReserve(){ if(!this.validateTime()) return; let self=this; let courseId=this.$route.params.courseId; let date=this.$route.params.date; this.baseAjax({ url:'../../../static/basicData/makeReserve.json', type:'get', showLoading:true, params:{ courseId:courseId, memberId:"666", reservedTime:self.checkTime.join(","), trainerId:"999" }, success:function(data){ console.log(data) if(data.isSuccess){ self.showSuccess=true; self.showReserveBtn=false; }else{ self.showError=true; } } }) }, //預約私教課 validateTime(){ if(!this.checkTime || this.checkTime.length!=2){ this.showMsg=true; return false } let type=this.activeType; let tlist=this.timeListArr[type]; let t1=tlist.indexOf(this.checkTime[0]); let t2=tlist.indexOf(this.checkTime[1]); if(Math.abs(t1-t2) !=1){ this.showMsg=true; return false } return true; } }, components:{ XImg,XButton,Flexbox, FlexboxItem,XDialog,Checker, CheckerItem,Toast } }
//groupCourses.vue <template> <div class="groupCourses"> <div class="topDate"> <tab :animate=false :line-width="1"> <tab-item disabled> <div class='left-calendar' @click="openCalendar()" > <p class="pickDate">{{pickDate}}</p> <p class="pickMonth">{{pickMonth}}月</p> </div> </tab-item> <tab-item @on-item-click="dateHandler(index)" v-for="(date,index) in dateList" :key="index" v-bind:class="{'vux-tab-selected': index==selectIndex ,'vux-tab-notSelected': index!=selectIndex}"> <p>{{date.week}}</p> <p>{{date.date}}</p> </tab-item> </tab> <div class="selectGroup"> <div class="purpose"> <div class="purpose-name group-head" @click="showPurpose=!showPurpose"> <flexbox> <flexbox-item :span="2"><div class="purpose-icon"><img src="../../../assets/images/icons/purpose_icon.png"></div></flexbox-item> <flexbox-item ><div>目的-{{coursesQueryData.purposeName}}</div></flexbox-item> <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item> </flexbox> </div> <div class="purpose-items group-items" v-show="showPurpose"> <p v-for="item in purposeList" @click="queryByPurpose(item)">{{item.name}}</p> </div> </div> <div class="categoryName"> <div class="category-name group-head" @click="showCategory=!showCategory"> <flexbox> <flexbox-item :span="2"><div class="purpose-icon"><img src="../../../assets/images/icons/category_icon.png"></div></flexbox-item> <flexbox-item ><div>分類-{{coursesQueryData.categoryName}}</div></flexbox-item> <flexbox-item :span="2"><div class="arrow-icon"><x-icon type="ios-arrow-down" size="20"></x-icon></div></flexbox-item> </flexbox> </div> <div class="category-items group-items" v-show="showCategory"> <p v-for="item in categoryList" @click="queryByCategory(item)">{{item.name}}</p> </div> </div> </div> </div> <div class="classItems"> <div class="activeItem" v-for="(item,index) in courseList" :key="index"> <img src="../../../assets/images/news-img.png"/> <div class='sbottom'> <p class="title">{{item.title}}</p> <p class="time-line"><span class='time'>{{item.startTime}} - {{item.endTime}}</span> <span class="view">{{item.viewer}}</span></p> </div> <div class="qtyProgress"> <div class='qbar' v-bind:style="{ width: item.barWidth,background:item.bgColor}"> </div> <div class="qty"><span>{{item.reservation}}</span> / <span>{{item.personMax}}</span></div> </div> <div class="bookBtn"> <x-button mini type="warn" action-type='button' @click.native="makeReserve(item.id,index)">預定</x-button> <!-- <x-button mini action-type='button' type="default">已預定</x-button> --> </div> </div> </div> <div> <popup v-model="showCalendar"> <inline-calendar @on-change="calendarChange" class="my-inline-calendar" v-model="calendarDate" :weeks-list="weeksList" > </inline-calendar> </popup> </div> <div> <x-dialog v-model="showSuccess" class="d-box" @click="showSuccess=false"> <div @click="showSuccess=false"> <div class="d-icon"> <img src="../../../assets/images/dialog-success.png"> </div> <p class="d-title">預定成功,記得準時簽到噢!</p> </div> </x-dialog> <x-dialog v-model="showSorry" class="d-box" > <div @click="showSorry=false"> <div class="d-icon"> <img src="../../../assets/images/dialog-sorry.png"> </div> <p class="d-title">人數已滿,下次記得早點預定噢!</p> </div> </x-dialog> </div> </div> </template> <script> import groupCourses from "./js/groupCourses.js" export default groupCourses </script> <style> .groupCourses .vux-tab .vux-tab-item{ line-height: 20px; } .groupCourses .pickDate { color:#DD5858; font-size: 16px; } .groupCourses .classItems{ margin-top: 145px; } .groupCourses .left-calendar{ margin-left:5px; border-radius: 5px; background: #eee; } .groupCourses .vux-tab{ height: 46px } .groupCourses .activeItem img{ width: 100% } .groupCourses .activeItem{ margin:10px 10px 0 10px; position: relative; height: 180px; overflow: hidden; border-radius: 5px } .groupCourses .topDate{ position: absolute; top: 52px; z-index: 10; width: 100%; } .groupCourses .activeItem .sbottom{ color: white; position: absolute; bottom: 10px; padding:10px; width: 85% } .groupCourses .activeItem .title{ font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .groupCourses .time-line{ font-size: 14px; width: 100%; height: 20px; } .groupCourses .activeItem .view{ float: right; font-size: 14px; } .groupCourses .activeItem img{ width: 100% } .groupCourses .vux-tab .vux-tab-item.vux-tab-disabled { color: #666; } .groupCourses .vux-tab .vux-tab-item.vux-tab-selected{ color:#DD5858; border-width: 3px !important; border-bottom: 3px solid #DD5858; } .groupCourses .bookBtn{ position: absolute; bottom: 20px; right: 20px; } .groupCourses button.weui-btn_mini{ width: 65px; padding: 0; } .groupCourses .selectGroup{ background: #fff } .groupCourses .group-head{ padding: 10px 0 5px 0; font-size: 14px; border-bottom: 1px solid #eee } .groupCourses .purpose-icon, .groupCourses .category-icon{ text-align: right; padding-right: 10px } .groupCourses .purpose-icon img{ height:20px; } .groupCourses .arrow-icon{ text-align: right; padding-right: 15px; } .groupCourses .group-items{ padding:0 30px; border-bottom: 1px solid #eee } .groupCourses .group-items p{ overflow: hidden; text-align: center; font-size: 14px; height: 30px; line-height:30px; color: #666; } .groupCourses .vux-tab .vux-tab-item.vux-tab-notSelected{ border-bottom:1px solid #eee; color: #666 } .groupCourses .inline-calendar td.current > span.vux-calendar-each-date { background-color: #DD5858; } .groupCourses .inline-calendar td.is-today{ color:#DD5858; } .groupCourses .qtyProgress{ width: 70px; position: absolute; top: 10px; left: 10px; border-radius: 10px; height: 20px; line-height: 20px; font-size: 12px; text-align: center; background: #666; color: #fff } .groupCourses .qbar{ border-radius: 10px; position: absolute; height: 100%; top: 0 } .groupCourses .qty{ text-align: center; width: 100%; border-radius: 10px; position: absolute; height: 100%; top: 0 } .groupCourses .d-box .d-title{ margin-bottom:15px; } .groupCourses .d-box .weui-dialog{ max-width: 240px; } .groupCourses .d-icon{ text-align: center; padding:10px; } .groupCourses .d-icon img{ height: 70px; margin:15px auto; } </style>
//groupCourses.js import { Tab, TabItem,XImg,dateFormat,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup,XDialog} from 'vux'; let cnM=['一','二','三','四','五','六','七','八','九','十','十一','十二']; // 獲取一週的日期 // 獲取當前星期的星期一的日期,返回的是一個Date對象。 function getMonDate(dd){ //config爲日期 例如:2016-04-19 let d=new Date(dd); let day=d.getDay(); let date=d.getDate(); if(day==1) return d; if(day==0) d.setDate(date-6); else d.setDate(date-day+1); return d; } //獲取一週的日期; function getWeekDate(self,confg){ let d=getMonDate(confg); let wkd=new Date(confg).getDay(); self.selectIndex=wkd==0?6:wkd-1 for(var i=0;i<7;i++){ self.dateList[i].date = d.getDate(); self.dateList[i].configDate=dateFormat(new Date(d), 'YYYY-MM-DD'); d.setDate(d.getDate()+1); } } export default { mounted() { this.$store.commit('UPDATE_PAGE_TITLE', '團體課') getWeekDate(this,this.myd); //加載一週數據 this.loadCourses(); //加載課程列表 }, data(){ let self=this; let data={ showSuccess:false, showSorry:false, calendarDate:"", dateList :[ {week:'週一',date:'',configDate:'',limit:false}, {week:'週二',date:'',configDate:'',limit:false}, {week:'週三',date:'',configDate:'',limit:false}, {week:'週四',date:'',configDate:'',limit:false}, {week:'週五',date:'',configDate:'',limit:false}, {week:'週六',date:'',configDate:'',limit:false}, {week:'週日',date:'',configDate:'',limit:false} ], myd:dateFormat(new Date(), 'YYYY-MM-DD'), pickMonth:cnM[new Date().getMonth()], pickDate:new Date().getDate(), selectIndex:null, courseList:'', showCategory:false, showPurpose:false, showCalendar:false, categoryList:[ {name:'所有',id:'1009'}, {name:'減肥',id:'1009'}, {name:'增肌',id:'1009'} ], purposeList:[ {name:'所有',id:'1009'}, {name:'健身操',id:'1009'}, {name:'瑜伽',id:'1009'}, {name:'動感單車',id:'1009'} ], weeksList:['日','一','二','三','四','五','六'], coursesQueryData:{ categoryId:"ioio", date:dateFormat(new Date(), 'YYYY-MM-DD'), purposeId:'yuyuy', categoryName:"所有", purposeName:"所有" } } return data }, methods:{ // 獲取團體課列表 loadCourses(){ let self=this; //與後端交互獲取數據 this.baseAjax({ url:'../../../static/basicData/groupCourse.json', params:{ categoryId:self.coursesQueryData.categoryId, date:self.coursesQueryData.date, purposeId:self.coursesQueryData.purposeId, }, showLoading:true, success:function(data){ console.log(data) self.courseList=data.returnObject; self.computListBar() } }) }, //選擇日期 calendarChange(date){ if(date==this.coursesQueryData.date) return; getWeekDate(this,date); this.coursesQueryData.date=date; this.showCalendar=false; this.loadCourses(); }, //頭部參課人數 computListBar(){ var self=this; var len=self.courseList.length; for(var i=0;i<len;i++){ var widthNo=(self.courseList[i].reservation/self.courseList[i].personMax).toFixed(2); self.courseList[i].barWidth=widthNo*100+"%"; if(widthNo<=0.5) { self.courseList[i].bgColor="#4FCC51" }else if(widthNo>0.5 && widthNo!=1) { self.courseList[i].bgColor="#E16F34"; }else if(widthNo==1){ self.courseList[i].bgColor="#DD5858"; } } }, //日期點擊事件 dateHandler(idx){ this.selectIndex=idx; this.coursesQueryData.date=this.dateList[idx].configDate; this.loadCourses(); }, //打開日期控件 openCalendar(){ this.showCalendar=true; }, //預約團體課程 makeReserve(id,idx){ let self=this; if(self.courseList[idx].reservation==self.courseList[idx].personMax){ self.showSorry=true; return; } this.baseAjax({ url:'../../../static/basicData/makeReserve.json', get:"post", params:{ courseId:id, memberId:"111" }, showLoading:true, success:function(data){ if(data.isSuccess){ self.courseList[idx].reservation=self.courseList[idx].reservation+1; self.showSuccess=true; self.computListBar(); } } }) }, //目的篩選課程 queryByPurpose(item){ this.showCategory=false; this.showPurpose=false; this.coursesQueryData.purposeId=item.id; this.coursesQueryData.purposeName=item.name; this.loadCourses(); }, //類別篩選課程 queryByCategory(item){ this.showCategory=false; this.showPurpose=false; this.coursesQueryData.categoryId=item.id; this.coursesQueryData.categoryName=item.name; this.loadCourses(); } }, components: { Tab,TabItem,XImg,XButton,Flexbox, FlexboxItem,InlineCalendar,Popup,XDialog } }
表白這位小姐姐,愛你呀謝謝你無私分享的精神鴨webpack