码迷,mamicode.com
首页 > 其他好文 > 详细

vue2-vux-fitness-project

时间:2019-05-06 14:39:55      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:play   exp   getters   join   been   mini   stand   alias   opd   

非常感谢那些无私开源的程序员,希望我也能够有能力像你们那样,开源很多很有意思的东西~~

//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;

固定头部和下部
技术图片

//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中是存储状态的

//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
    }
  }

表白这位小姐姐,爱你呀谢谢你无私分享的精神鸭

vue2-vux-fitness-project

标签:play   exp   getters   join   been   mini   stand   alias   opd   

原文地址:https://www.cnblogs.com/smart-girl/p/10819272.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!