zoukankan      html  css  js  c++  java
  • 【生活美好】youya-vue

    这是一个比较大的项目哦
    先放上作者的github地址
    https://github.com/z8985561/youya-vue
    然后我们来大体看看有什么效果

    接下来我们一起来分析项目啦
    首先是main.js

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import Axios from "axios";
    import VueAxios from "vue-axios";
    // 适配方案
    import 'lib-flexible/flexible.js';
    
    // 公共样式
    import './assets/css/common.css';
    
    import VueLazyload from 'vue-lazyload'
    
    Vue.use(VueLazyload)
    
    // 引入 vant-ui
    import Vant from 'vant';
    import 'vant/lib/index.css';
    Vue.use(Vant);
    
    Vue.config.productionTip = false
    
    const IS_TEST = true;
    
    // Axios 请求
    Axios.defaults.timeout = 30000;
    Axios.defaults.withCredentials = true;
    Axios.interceptors.response.use(response => {
      if (response.status === 200) {
        if (!IS_TEST && response.data.code == 401) {
          window.console.log(response.data.code);
          window.location.href = `http://youya.chuncom.com/user/authorization?url=${encodeURIComponent(
                  window.location.href
                )}`;
          return;
        }
        return Promise.resolve(response.data);
      } else {
        return Promise.reject(response.data);
      }
    }, error => {
      if (error.response.status) {
        console.log(error)
        // switch (error.response.status) {
        //   case 401:
        //     router.replace({
        //       path: '/',
        //       query: {
        //         redirect: router.currentRoute.fullPath
        //       }
        //     });
        //     break;
        //   default:
        //     console.log(123)
        // }
        return Promise.reject(error.response);
      }
    })
    window.axios = Axios;
    
    router.beforeEach((to, from, next) => {
      /* 路由发生变化修改页面title */
      if (to.meta.title) {
        document.title = to.meta.title
        // console.log(store)
      }
      next()
    })
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    

    接下来就是router.js

    import Vue from 'vue'
    import Router from 'vue-router'
    import Index from './views/Index.vue'
    
    Vue.use(Router)
    
    export default new Router({
      mode: 'history',
      base: process.env.BASE_URL,
      routes: [{
        // 首页
        path: '/',
        name: 'index',
        component: Index,
        meta: {
          title: "首页",
          keepAlive: true
        }
      },
      {
        // 课程
        path: '/video',
        name: 'video',
        component: () => import( /* webpackChunkName: "about" */ './views/Video.vue'),
        meta: {
          title: "课程",
          keepAlive: true
        }
      },
      {
        // 视频课程详情
        path: '/video_detail',
        name: 'video_detail',
        component: () => import( /* webpackChunkName: "about" */ './views/VideoDetail.vue'),
        meta: {
          title: "课程详情"
        }
      },
      // SharePosters.vue
      {
        // 分享海报
        path: '/share_posters/:id',
        name: 'share_posters',
        component: () => import( /* webpackChunkName: "about" */ './views/SharePosters.vue'),
        meta: {
          title: "课程详情"
        }
      },
      // ToolDetail.vue
      {
        // 功能单页面详情
        path: '/tool_detail/:id',
        name: 'tool_detail',
        component: () => import('./views/ToolDetail.vue'),
        meta: {
          title: "",
          keepAlive: true
        }
      },
      {
        // 文章
        path: '/article',
        name: 'article',
        component: () => import('./views/Article.vue'),
        meta: {
          title: "文章",
          keepAlive: true
        }
      },
      {
        // 体验课程
        path: '/experience/:id',
        name: 'experience',
        component: () => import('./views/Experience.vue'),
        meta: {
          title: "体验课程",
          keepAlive: true
        }
      },
      // ArticleList.vue
      {
        // 优雅美文
        path: '/article_list',
        name: 'article_list',
        component: () => import('./views/ArticleList.vue'),
        meta: {
          title: "优雅美文",
          keepAlive: true
        }
      },
      // CreateOrder.vue
      {
        // 确认购买
        path: '/create_order',
        name: 'create_order',
        component: () => import('./views/CreateOrder.vue'),
        meta: {
          title: "确认购买"
        }
      },
      // Feedback.vue
      {
        // 确认购买
        path: '/feedback',
        name: 'video_feedback',
        component: () => import('./views/Feedback.vue'),
        meta: {
          title: "确认购买"
        }
      },
      // SubscribeList.vue
      {
        // 预约
        path: '/subscribe_list',
        name: 'subscribe_list',
        component: () => import('./views/SubscribeList.vue'),
        meta: {
          title: "预约",
          keepAlive: true
        }
      },
      // SubscribeDetail
      {
        // 预约
        path: '/subscribe_detail/:id',
        name: 'subscribe_detail',
        component: () => import('./views/SubscribeDetail.vue'),
        meta: {
          title: "预约详情"
        }
      },
      // SubscribeAuth.vue
      {
        // 预约
        path: '/subscribe_auth/:course_id',
        name: 'subscribe_auth',
        component: () => import('./views/SubscribeAuth.vue'),
        meta: {
          title: "预约详情"
        }
      },
      // BindingInformation.vue
      {
        // 用户手机绑定
        path: '/binding_information',
        name: 'binding_information',
        component: () => import('./views/BindingInformation.vue'),
        meta: {
          title: "用户手机绑定"
        }
      },
      // Authentication
      {
        // 身份验证
        path: '/authentication',
        name: 'authentication',
        component: () => import('./views/Authentication.vue'),
        meta: {
          title: "身份验证"
        }
      },
      // Authentication
      {
        // 个人中心
        path: '/member',
        name: 'member_index',
        component: () => import('./views/member/Index.vue'),
        meta: {
          title: "个人中心",
          keepAlive: true
        }
      },
      // PackageGift.vue
      {
        // 提现
        path: '/member/package_gift',
        name: 'member_package_gift',
        component: () => import('./views/member/PackageGift.vue'),
        meta: {
          title: " 转赠课程"
        }
      },
      // Withdraw.vue
      {
        // 提现
        path: '/member/withdraw',
        name: 'member_withdraw',
        component: () => import('./views/member/Withdraw.vue'),
        meta: {
          title: "提现"
        }
      },
      // MyCoursesList.vue
      {
        // 我的课次
        path: '/member/my_courses_list',
        name: 'my_courses_list',
        component: () => import('./views/member/MyCoursesList.vue'),
        meta: {
          title: "我的课次"
        }
      },
      // DonationCourses.vue
      {
        // 转赠课程
        path: '/member/donation_courses',
        name: 'donation_courses',
        component: () => import('./views/member/DonationCourses.vue'),
        meta: {
          title: "转赠课程"
        }
      },
      // MyReservation.vue
      {
        // 我的预约
        path: '/member/my_reservation_list',
        name: 'my_reservation_list',
        component: () => import('./views/member/MyReservationList.vue'),
        meta: {
          title: "我的预约"
        }
      },
      // MyVideoList.vue
      {
        // 我的视频
        path: '/member/my_video_list',
        name: 'my_video_list',
        component: () => import('./views/member/MyVideoList.vue'),
        meta: {
          title: "我的视频"
        }
      },
      // MyRedeemCode.vue
      {
        // 我的兑换码
        path: '/member/produce_code',
        name: 'produce_code',
        component: () => import('./views/member/ProduceCode.vue'),
        meta: {
          title: "我的兑换码"
        }
      },
      // MyRedeemCode.vue
      {
        // 我的兑换码
        path: '/member/my_redeem_code',
        name: 'my_redeem_code',
        component: () => import('./views/member/MyRedeemCode.vue'),
        meta: {
          title: "我的兑换码"
        }
      },
      //WithdrawRecord.vue
      {
        // 提现记录
        path: '/member/withdraw_record',
        name: 'withdraw_record',
        component: () => import('./views/member/WithdrawRecord.vue'),
        meta: {
          title: "提现记录"
        }
      },
      //EarningsRecord.vue
      {
        // 收益记录
        path: '/member/earnings_record',
        name: 'earnings_record',
        component: () => import('./views/member/EarningsRecord.vue'),
        meta: {
          title: "收益记录"
        }
      },
      //EarningsRecord.vue
      {
        // 收益记录
        path: '/member/earnings_record2',
        name: 'earnings_record2',
        component: () => import('./views/member/EarningsRecord2.vue'),
        meta: {
          title: "收益记录"
        }
      },
      // PersonalInfo.vue
      {
        // 个人资料
        path: '/member/personal_info',
        name: 'personal_info',
        component: () => import('./views/member/PersonalInfo.vue'),
        meta: {
          title: "个人资料"
        }
      },
      // AddressList.vue
      {
        // 地址管理
        path: '/member/address_list',
        name: 'address_list',
        component: () => import('./views/member/AddressList.vue'),
        meta: {
          title: "地址管理"
        }
      },
      // AddressEdit.vue
      {
        // 地址编辑
        path: '/member/address_edit',
        name: 'address_edit',
        component: () => import('./views/member/AddressEdit.vue'),
        meta: {
          title: "地址编辑"
        }
      },
      // MyCart.vue
      {
        // 我的购物车
        path: '/member/my_cart',
        name: 'my_cart',
        component: () => import('./views/member/MyCart.vue'),
        meta: {
          title: "我的购物车"
        }
      },
      {
        // 核销单首页
        path: '/verification/index',
        name: 'verification_index',
        component: () => import('./views/verification/Index.vue'),
        meta: {
          title: "香港皇家优雅女子学堂"
        }
      },
      // OrderManage.vue
      {
        // 订单管理
        path: '/verification/order_manage',
        name: 'order_manage',
        component: () => import('./views/verification/OrderManage.vue'),
        meta: {
          title: "订单管理"
        }
      },
      // OrderDetail.vue
      {
        // 订单核销
        path: '/verification/order_detail',
        name: 'verification_order_detail',
        component: () => import('./views/verification/OrderDetail.vue'),
        meta: {
          title: "订单核销"
        }
      },
    
      {
        // 转赠课程包管理页面
        path: '/reservation/order_manage',
        name: 'reservation_order_manage',
        component: () => import('./views/reservation/OrderManage.vue'),
        meta: {
          title: "转赠课程管理"
        }
      },
      {
        // 转赠课程包详情核销
        path: '/reservation/order_detail',
        name: 'reservation_order_detail',
        component: () => import('./views/reservation/OrderDetail.vue'),
        meta: {
          title: "转赠课程核销"
        }
      },
      // Feedback.vue
      {
        // 反馈页面
        path: '/verification/feedback',
        name: 'feedback',
        component: () => import('./views/verification/Feedback.vue'),
        meta: {
          title: "反馈页面"
        }
      },
      // 产品列表
      {
        // 产品列表
        path: '/goods/index',
        name: 'goods_index',
        component: () => import('./views/goods/Index.vue'),
        meta: {
          title: "商品列表"
        }
      },
      // 产品列表
      {
        // 产品列表
        path: '/goods/index2',
        name: 'goods_index2',
        component: () => import('./views/goods/Index2.vue'),
        meta: {
          title: "商品列表"
        }
      },
      // 产品详情
      {
        // 产品详情
        path: '/goods_detail',
        name: 'goods_detail',
        component: () => import('./views/goods/Detail.vue'),
        meta: {
          title: "商品详情"
        }
      },
      // 商品创建订单 CreateOrder.vue
      {
        // 确认订单
        path: '/goods_create_order',
        name: 'goods_create_order',
        component: () => import('./views/goods/CreateOrder.vue'),
        meta: {
          title: "确认订单"
        }
      },
      // 订单支付反馈页面
      {
        // 订单支付反馈页面
        path: '/goods/pay_feedback',
        name: 'goods_pay_feedback',
        component: () => import('./views/goods/Feedback.vue'),
        meta: {
          title: ""
        }
      },
      // BranchList.vue
      {
        // 全国分院列表
        path: '/branch',
        name: 'branch_list',
        component: () => import('./views/branch/BranchList.vue'),
        meta: {
          title: "全国分院列表",
          keepAlive: true
        }
      },
      // BranchDetail.vue
      {
        // 分院详情
        path: '/branch/detail',
        name: 'branch_detail',
        component: () => import('./views/branch/BranchDetail.vue'),
        meta: {
          title: "分院详情"
        }
      },
      // 订单列表
      // OrderList.vue.vue
      {
        // 订单列表
        path: '/order_list',
        name: 'order_list',
        component: () => import('./views/order/OrderList.vue'),
        meta: {
          title: "订单列表"
        }
      },
      {
        // 订单详情
        path: '/order_detail',
        name: 'order_detail',
        component: () => import('./views/order/OrderDetail.vue'),
        meta: {
          title: "订单详情"
        }
      },
      {
        // 申请退款
        path: '/order/refund/:id',
        name: 'order_refund',
        component: () => import('./views/order/Refund.vue'),
        meta: {
          title: "申请退款"
        }
      },
      // RefundDetail.vue
      {
        // 退款详情
        path: '/order/refund_detail/:id',
        name: 'order_refund_detail',
        component: () => import('./views/order/RefundDetail.vue'),
        meta: {
          title: "退款详情"
        }
      },
      {
        // 梦想导师团
        path: '/tutor/index',
        name: 'tutor_index',
        component: () => import('./views/tutor/Index.vue'),
        meta: {
          title: "梦想导师团",
          keepAlive: true
        }
      },
      {
        // 梦想导师团
        path: '/tutor/detail',
        name: 'tutor_detail',
        component: () => import('./views/tutor/Detail.vue'),
        meta: {
          title: "梦想导师团"
        }
      },
      // 二期新增
      {
        // 服务对象ServiceObject.vue
        path: '/member/service_object',
        name: 'service_object',
        component: () => import('./views/member/ServiceObject.vue'),
        meta: {
          title: "服务对象"
        }
      },
      {
        // 服务对象ServiceObject.vue
        path: '/member/service_object2',
        name: 'service_object2',
        component: () => import('./views/member/ServiceObject2.vue'),
        meta: {
          title: "大使服务对象"
        }
      },
      {
        // 服务对象ServiceObject.vue
        path: '/member/my_ambassador',
        name: 'my_ambassador',
        component: () => import('./views/member/MyAmbassador.vue'),
        meta: {
          title: "我的传播大使"
        }
      },
      {
        // 业绩排行榜
        path: '/member/rank_list',
        name: 'rank_list',
        component: () => import('./views/member/RankList.vue'),
        meta: {
          title: "业绩排行榜"
        }
      },
      {
        // 课程列表
        path: '/live_list',
        name: 'live_list',
        component: () => import('./views/live/LiveList.vue'),
        meta: {
          title: "课程列表"
        }
      },
      {
        // 课程详情
        path: '/live_detail',
        name: 'live_detail',
        component: () => import('./views/live/LiveDetail.vue'),
        meta: {
          title: "课程详情"
        }
      },
      {
        // 直播课程
        path: '/live/my_live',
        name: 'my_live',
        component: () => import('./views/live/MyLive.vue'),
        meta: {
          title: "直播课程"
        }
      },
      {
        // 直播课程
        path: '/live/my_live_detail',
        name: 'my_live_detail',
        component: () => import('./views/live/MyLiveDetail.vue'),
        meta: {
          title: "直播课程"
        }
      },
      {
        // 直播课程
        path: '/live/feedback',
        name: 'live_feedback',
        component: () => import('./views/live/Feedback.vue'),
        meta: {
          title: "直播课程"
        }
      },
      {
        // 确认购买
        path: '/live_create',
        name: 'live_create',
        component: () => import('./views/live/Create.vue'),
        meta: {
          title: "确认购买"
        }
      },
      {
        // 确认购买
        path: '/upgrade',
        name: 'upgrade',
        component: () => import('./views/upgrade/Upgrade.vue'),
        meta: {
          title: ""
        }
      },
      {
        // 升级课程详情
        path: '/upgrade_detail',
        name: 'upgrade_detail',
        component: () => import('./views/upgrade/UpgradeDetail.vue'),
        meta: {
          title: "课程详情"
        }
      },
      {
        // 升级课程下单
        path: '/upgrade_create',
        name: 'upgrade_create',
        component: () => import('./views/upgrade/Create.vue'),
        meta: {
          title: "课程详情"
        }
      },
      {
        // 升级课程支付反馈
        path: '/upgrade_feedback',
        name: 'upgrade_feedback',
        component: () => import('./views/upgrade/Feedback.vue'),
        meta: {
          title: ""
        }
      },
      {
        // 升级课程支付反馈
        path: '/upgrade_order',
        name: 'upgrade_order',
        component: () => import('./views/upgrade/Detail.vue'),
        meta: {
          title: ""
        }
      }
      ]
    })
    

    接下来是App.vue

    <template>
      <div id="app">
        <router-view>
        </router-view>
        <keep-alive>
          <!-- 底部菜单 -->
          <FooterNav v-if="$route.meta.keepAlive" />
          <!-- 底部菜单 -->
        </keep-alive>
      </div>
    </template>
    <script>
      import FooterNav from "./components/FooterNav"
      export default {
        components: {
          FooterNav
        },
        mounted() {
          window.addEventListener('focusout', function() {
            document.body.scrollTop = document.body.scrollHeight;
          })
        },
      }
    </script>
    <style lang="less">
      #app {
        padding-bottom: 60px;
        background-color: #fff;
      }
    </style>
    

    然后是footer组件

    <template>
      <div>
        <van-tabbar v-model="index" active-color="#8DB9DF"
      inactive-color="#999999">
          <van-tabbar-item replace to="/">
            <span>首页</span>
            <img
              slot="icon"
              slot-scope="props"
              :src="props.active ? icons[0].active : icons[0].normal"
            >
          </van-tabbar-item>
          <van-tabbar-item replace to="/video">
            <span>视频</span>
            <img
              slot="icon"
              slot-scope="props"
              :src="props.active ? icons[1].active : icons[1].normal"
            >
          </van-tabbar-item>
          <van-tabbar-item replace to="/subscribe_list">
            <span>预约</span>
            <img
              slot="icon"
              slot-scope="props"
              :src="props.active ? icons[2].active : icons[2].normal"
            >
          </van-tabbar-item>
          <van-tabbar-item replace to="/member">
            <span>我的</span>
            <img
              slot="icon"
              slot-scope="props"
              :src="props.active ? icons[3].active : icons[3].normal"
            >
          </van-tabbar-item>
        </van-tabbar>
      </div>
    </template>
    <script>
    export default {
      props: ["active"],
      data(){
        return{
          index:0,
          icons:[{
            normal: 'http://youya.chuncom.com/youya-h5/img/home-normal.png',
            active: 'http://youya.chuncom.com/youya-h5/img/home-active.png'
          },{
            normal: 'http://youya.chuncom.com/youya-h5/img/video-normal.png',
            active: 'http://youya.chuncom.com/youya-h5/img/video-active.png'
          },{
            normal: 'http://youya.chuncom.com/youya-h5/img/clock-normal.png',
            active: 'http://youya.chuncom.com/youya-h5/img/clock-active.png'
          },{
            normal: 'http://youya.chuncom.com/youya-h5/img/user-normal.png',
            active: 'http://youya.chuncom.com/youya-h5/img/user-active.png'
          }]
        }
      },
      mounted() {
        this.index = this.active || 0 ;
        console.log(this.$router.currentRoute.name)
      },
    }
    </script>
    <style lang="less">
      .van-tabbar-item__icon img{
         24px;
        height: 24px !important;
      }
    </style>
    

    接下来我们看首页的写法

    <template>
      <div class="plr-15 pt-10">
        <!-- 轮播图 -->
        <div class="mb-10">
          <van-swipe :autoplay="3000" :show-indicators="false">
            <van-swipe-item v-for="item in banner" :key="item.id">
              <!-- <router-link :to="item.url">
                <img :src="item.image" width="100%" alt="">
              </router-link>-->
              <a :href="item.url">
                <img :src="item.image" width="100%" alt />
              </a>
            </van-swipe-item>
          </van-swipe>
        </div>
        <!-- 轮播图 -->
        <!-- banner -->
        <div class="flex flex-jus">
          <div v-for="item in ad" :key="item.id" class="banner2">
            <!-- <router-link :to="item.url">
              <img :src="item.image" width="100%" alt="">
            </router-link>-->
            <a :href="item.url">
              <img :src="item.image" width="100%" alt />
            </a>
          </div>
          <!-- <div class="banner2">
            <router-link to="/goods/index">
              <img src="/img/banner2-02.png" width="100%" alt="">
            </router-link>
          </div>-->
        </div>
        <!-- banner -->
        <!-- 菜单 -->
        <van-grid :column-num="5" :border="false">
          <van-grid-item v-for="item in tool" :icon="item.image" :text="item.title" :to="{ name: 'tool_detail', params: { id: item.id }}" />
        </van-grid>
        <!-- 菜单 -->
    
        <!-- 升级课程 -->
        <div class="flex flex-wrap flex-jus mb-10">
          <div v-for="(item,index) in upgradeInfo" :key="index" class="course-item">
            <router-link :to="{name:'upgrade_detail',query:{id:item.id}}">
              <img v-lazy="item.image" width="100%" alt />
            </router-link>
          </div>
        </div>
    
    
        <!-- 升级课程 -->
    
    
        <!-- 课程推荐 -->
        <div class="flex flex-wrap flex-jus mb-10">
          <div class="course-item">
            <router-link to="/video">
              <img v-lazy="tool_parameter.HOME_SOURSE_IMAGE" width="100%" alt />
            </router-link>
          </div>
          <div class="course-item">
            <router-link to="/subscribe_list">
              <img v-lazy="tool_parameter.HOME_BOOKING_IMAGE" width="100%" alt />
            </router-link>
          </div>
          <div class="course-item">
            <router-link to="/article_list">
              <img v-lazy="tool_parameter.HOME_ARTICLE_IMAGE" width="100%" alt />
            </router-link>
          </div>
          <div class="course-item">
            <router-link to="/goods/index">
              <img v-lazy="tool_parameter.HOME_OFFSOURSE_IMAGE" width="100%" alt />
            </router-link>
          </div>
        </div>
        <!-- 课程推荐 -->
        <!-- 视频列表 -->
        <h2 class="fz-16 c3 mb-10 flex flex-jus flex-align-center">
          <div>直播课程</div>
          <router-link :to="{name:'live_list'}">
            <span class="fz-11 c9">查看跟多</span>
            <van-icon name="arrow" size="11" color="#999" />
          </router-link>
          </rou>
        </h2>
        <!-- <van-grid :border="false" :column-num="4">
          <van-grid-item v-for="(item ,index) in liveList" :key="index" :to="{name:'live_list',query:{id:item.id}}">
            <div class="live-item">
              <div>{{ item.name }}</div>
            </div>
          </van-grid-item>
        </van-grid> -->
        <div class="video-list mb-10">
          <div class="video-item" v-for="(item,index) in liveList" :key="index">
            <router-link :to="{name:'live_detail',query:{id:item.id}}">
              <div class="video-img">
                <img :src="item.image" width="100%" alt />
              </div>
            </router-link>
          </div>
        </div>
        <!-- 视频列表 -->
    
        <!-- 视频列表 -->
        <h2 class="fz-16 c3 mb-10">热门课程</h2>
        <div class="video-list mb-10">
          <div class="video-item" v-for="(item,index) in CourseHot" :key="index">
            <router-link :to="{ name: 'video_detail', query: { id: item.id }}">
              <div class="video-img">
                <img :src="item.image" width="100%" alt />
                <div class="sets">更新至{{item.period}}集</div>
              </div>
              <div class="fz-14 c3 text-hide">{{item.name}}</div>
              <div class="fz-14 text-price">¥{{item.price}}</div>
            </router-link>
          </div>
        </div>
        <!-- 视频列表 -->
    
        <!-- banner3 -->
        <div class="mb-10">
          <router-link :to="{name:'experience',params:{id:1}}">
            <img v-lazy="tool_parameter.HOME_EXPERIENCE_IMAGE" width="100%" alt />
          </router-link>
        </div>
        <div class="mb-10">
          <router-link to="/branch">
            <img v-lazy="tool_parameter.HOME_BRANCH_IMAGE" width="100%" alt />
          </router-link>
        </div>
        <div v-if="ad_foot.length" class="mb-10">
          <router-link to="/tutor/index">
            <img v-lazy="ad_foot[0].image" width="100%" alt />
          </router-link>
        </div>
        <div v-if="ad_foot.length" class="mb-10" style="margin-bottom:2.666667rem;">
          <router-link to="/goods/index2">
            <img v-lazy="ad_foot[1].image" width="100%" alt />
          </router-link>
        </div>
        <!-- banner3 -->
        <!-- banner -->
        <!-- <div v-if="ad_foot.length" class="flex flex-jus" style="margin-bottom:2.666667rem;">
          <div v-for="(item,index) in ad_foot" v-if="index !=0" :key="item.id" class="banner2">
            <a :href="item.url">
              <img :src="item.image" width="100%" alt="">
            </a>
          </div>
        </div>-->
        <!-- banner -->
        <!-- 联系我们 -->
        <div class="contact-us">
          <div class="logo">
            <img src="img/logo.png" alt />
          </div>
          <div v-html="tool_parameter.HOME_BOTTOM_TEXT"></div>
          <!-- <p>欢迎您的加入!</p>
          <p>香港皇家优雅女子学堂提供的不仅是一个课程,也是一种优雅的生活方式更是一个精神的殿堂!</p>
          <p>联系方式:020-38868921 · 020-38847236</p>
          <p>中国总部:广州市天河区体育东路108号创展中心</p>
          <p>(万凌汇旁)西座三楼</p>-->
        </div>
        <!-- 联系我们 -->
      </div>
    </template>
    <script>
      import wx from "weixin-js-sdk";
      export default {
        data() {
          return {
            active: 1,
            images: [
              "../assets/img/index-banner-01.png",
              "../assets/img/index-banner-01.png"
            ],
            ad: "",
            ad_foot: [],
            banner: "",
            tool: "",
            tool_parameter: "",
            CourseHot: [],
            liveList: [],
            upgradeInfo: []
          };
        },
        created() {
          this.activity_id = this.$route.query.activity_id;
          this.share_id = this.$route.query.share_id;
          this.getContactImg();
          if (this.$route.query.type) {
            this.jumpPage();
          } else {
            this.checkLogin();
          }
          this.getSDK();
          this.getLive();
          this.getUpgradeInfo();
        },
        methods: {
          async getUpgradeInfo() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/home/upgrade-info");
            if (code == 0) {
              window.console.log(data);
              this.upgradeInfo = data;
            } else {
              window.console.error(message);
            }
          },
          async getLive() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/home/live");
            if (code == 0) {
              // window.console.log(data);
              this.liveList = data;
            } else {
              window.console.error(message);
            }
          },
          async getContactImg() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/config/detail", {
              params: {
                key: "CUSTOMER_CONTACT"
              }
            });
            if (code == 0) {
              this.$store.dispatch("setContact", data.value);
            } else {
              window.console.error(message);
            }
          },
          // 根据type跳转到不同的页面
          jumpPage() {
            let type = this.$route.query.type;
            switch (type) {
              case "1":
                this.$router.push({
                  name: "article",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id
                  }
                });
                break;
              case "2":
                this.$router.push({
                  name: "video_detail",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id
                  }
                });
                break;
              case "3":
                this.$router.push({
                  name: "goods_detail",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id
                  }
                });
                break;
              case "4":
                this.$router.push({
                  name: "subscribe_detail",
                  params: {
                    id: this.$route.query.id
                  }
                });
                break;
              case "5":
                this.$router.push({
                  name: "live_detail",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id
                  }
                });
                break;
              case "6":
                this.$router.push({
                  name: "upgrade_detail",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id
                  }
                });
                break;
              default:
                this.checkLogin();
                break;
            }
          },
          async login() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/user/login?id=1");
            if (code == 0) {
              this.getData();
              this.getCourseHot();
              data = JSON.stringify(data);
              localStorage.setItem("userinfo", data);
            }
          },
          async checkLogin() {
            this.$toast.loading({
              message: "加载中..."
            });
            let {
              data,
              code
            } = await window.axios.get("/user");
            this.$toast.clear();
            if (code == 0) {
              data = JSON.stringify(data);
              localStorage.setItem("userinfo", data);
              this.getData();
              this.getCourseHot();
            } else if (code == 401) {
              this.login();
              // let href = encodeURIComponent(window.location.href);
              // window.location.href =
              //   "http://youya.chuncom.com/user/authorization?url=" + href;
            }
          },
          async getSDK() {
            // alert(location.href)
            let href = encodeURIComponent(window.location.href);
            let {
              data,
              code,
              message
            } = await window.axios.get(
              "/config/jsjdk?url=" + href
            );
            if (code == 0) {
              wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: data.appId, // 必填,公众号的唯一标识
                timestamp: Number(data.timestamp), // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature, // 必填,签名,见附录1
                jsApiList: [
                  "chooseWXPay",
                  "onMenuShareTimeline",
                  "onMenuShareAppMessage", //1.0分享到朋友圈
                  "updateAppMessageShareData", //1.4 分享到朋友
                  "updateTimelineShareData",
                  "openAddress"
                ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
              });
            } else {
              // $weui.topTips(message, 3000);
            }
          },
          async getData() {
            this.$toast.loading({
              message: "加载中..."
            });
            let {
              code,
              data,
              message
            } = await window.axios.get("/home");
            if (code == 0) {
              this.$toast.clear();
              this.ad = data.ad;
              this.banner = data.banner;
              this.tool = data.tool;
              this.tool_parameter = data.tool_parameter;
              this.ad_foot = data.ad_foot;
            } else {
              this.$toast.fail(message);
            }
          },
          async getCourseHot() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/home/course-hot");
            if (code == 0) {
              this.CourseHot = data;
            } else {
              this.$toast.fail(message);
            }
          }
        }
      };
    </script>
    <style lang="less">
      .van-uploader__input {
        right: 0;
        left: -40vw !important;
         60vw !important;
      }
    
      .van-icon__image {
         45px !important;
        height: 45px !important;
      }
    
      .van-grid-item__text {
        color: #999 !important;
      }
    
      .course-item {
        margin-bottom: 10px;
         168px;
    
        img {
           100%;
          vertical-align: bottom;
        }
      }
    
      .banner2 {
         168px;
    
        img {
           100%;
          vertical-align: bottom;
        }
      }
    
      .video-list {
         100%;
        overflow-x: scroll;
        white-space: nowrap;
    
        .video-item {
          display: inline-block;
          margin-right: 10px;
           168px;
    
          .video-img {
            position: relative;
            margin-bottom: 5px;
    
            .sets {
              position: absolute;
              right: 7px;
              bottom: 2px;
              font-size: 11px;
              color: #fff;
            }
          }
        }
      }
    
      .contact-us {
        position: relative;
        border-top: 4px dotted #eee;
        border-bottom: 4px dotted #eee;
        padding: 46px 0 17px;
    
        .logo {
          position: absolute;
          background-color: #fff;
          padding: 0 24px;
          left: 50%;
          top: 0;
          transform: translate(-50%, -60%);
    
          img {
             90px;
          }
        }
    
        p {
          color: #bcbcbc;
          font-size: 12px;
          text-align: center;
        }
      }
    
      .live-item {
         100%;
        height: 40px;
        line-height: 40px;
        background: rgba(255, 255, 255, 1);
        border-radius: 20px;
        border: 1px solid rgba(236, 236, 236, 1);
        color: #333;
        text-align: center;
        font-size: 12px;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    </style>
    

    看着内容挺多的,然后其实用了van这个Ui组件之后,再加上异步的渲染,其实很简洁很高效
    接下来看品牌故事页面

    <template>
      <div>
        <div v-html="content"></div>
      </div>
    </template>
    
    <script>
    export default {
      components: {},
      props: {},
      data() {
        return {
          content:""
        };
      },
      watch: {},
      computed: {},
      methods: {
        async getData(){
          this.$toast.loading({messages:"加载中..."})
          let {code,data,messages} = await axios.get(`/home/tool-detail?id=${this.$route.params.id}`);
          if(code==0){
              this.$toast.clear();
              this.content = data.detail;
              document.title = data.title
            }else{
              this.$toast.fail(messege)
            }
        },
        async getAbout(){
          this.$toast.loading({messages:"加载中..."})
          let {code,data,messages} = await axios.get(`/config/detail?key=ABOUT_US`);
          if(code==0){
            this.$toast.clear();
            this.content = data.value;
            document.title = data.tip;
          }else{
            this.$toast.fail(messege)
          }
        }
      },
      created() {
        if(this.$route.query.key){
          this.getAbout()
        }else{
          this.getData()
        }
    
      },
      mounted() {}
    };
    </script>
    <style lang="less" scoped>
    </style>
    

    这个content不知道是哪里来的
    打印结果,居然是H5的切片,有意思极了
    接下来我们看

    //UpgradeDetail
    <template>
      <div>
        <img :src="detail.image" class="live-banner" alt />
        <!-- 课程信息 -->
        <div class="p-15 flex mb-10">
          <div class="course-info">
            <h2 class="fz-17 c3 mb-5">{{detail.name}}</h2>
            <!-- <div class="fz-12 c9 mb-5">全部{{catalogue.length || 0}}集</div> -->
            <div>
              <span class="fz-15 text-price">¥{{detail.bug_info.price}} </span>
              <span class="fz-12 c9 text-line">原价¥{{detail.bug_info.original_price}}</span>
            </div>
          </div>
          <div v-if="detail.is_share" @click="isShowPoster = true" class="course-share flex flex-align-start">
            <div class="flex flex-column flex-jus flex-align-center">
              <img src="@/assets/img/icon-wallet.png" alt />
              <div class="fz-11 c9">分享获得</div>
            </div>
            <div class="award-tips">{{parseInt(detail.share_amount||0)}}元奖励</div>
          </div>
        </div>
        <!-- 课程信息 -->
        <div class="bar-10"></div>
        <!-- 课程详情和目录 -->
        <van-tabs v-model="active" title-active-color="#8DB9DF" title-inactive-color="#999999" color="#8DB9DF">
          <van-tab title="课程详情">
            <div class="p-15" v-html="detail.detail"></div>
          </van-tab>
          <van-tab title disabled></van-tab>
        </van-tabs>
        <!-- 课程详情和目录 -->
    
        <!-- footer -->
        <div class="footer-bar plr-15 flex flex-align-center">
          <router-link to="/">
            <div class="back-home">
              <img src="@/assets/img/icon-home.png" alt />
              <div class="fz-11 c9">首页</div>
            </div>
          </router-link>
          <div v-if="detail.is_bug == 0" class="btn-youya" @click="buying">购买课程</div>
          <div v-else class="btn-youya disable">已购买</div>
        </div>
        <!-- footer -->
        <!-- 侧边客服购物车按钮 -->
        <div class="side-btn">
          <img @click="showContact" src="@/assets/img/btn-service.png" alt />
        </div>
        <van-popup v-model="isShowContact">
          <img style="70vw;" :src="this.$store.getters.getContact" alt />
        </van-popup>
        <!-- 侧边客服购物车按钮 -->
    
        <van-popup v-model="isShowPoster">
          <img :src="imgUrl || this.detail.share_info.share_qr" class="poster" alt />
        </van-popup>
    
      </div>
    </template>
    
    <script>
      import MCanvas from "mcanvas";
      // require styles
      import wx from "weixin-js-sdk";
      export default {
        props: {},
        data() {
          return {
            show: false,
            flag: false,
            isShowPoster: false,
            active: 0,
            isShowContact: false,
            showVideo: false,
            // 是否购买该教程
            isbought: false,
            catalogue: [],
            detail: "",
            userinfo: {},
            imgUrl: ""
          };
        },
        watch: {},
        computed: {},
        methods: {
          async add() {
            if (!this.$route.query.share_id) {
              return;
            }
            let {
              code
            } = await window.axios.post("/user/superior/add", {
              superior_id: this.$route.query.share_id
            });
            if (code == 0) {
              window.console.log("绑定成功");
            }
          },
          showContact() {
            this.isShowContact = true;
          },
          async getSDK() {
            // alert(location.href)
            let href = encodeURIComponent(window.location.href);
            let {
              data,
              code,
              message
            } = await window.axios.get(
              "/config/jsjdk?url=" + href
            );
            if (code == 0) {
              wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: data.appId, // 必填,公众号的唯一标识
                timestamp: Number(data.timestamp), // 必填,生成签名的时间戳
                nonceStr: data.nonceStr, // 必填,生成签名的随机串
                signature: data.signature, // 必填,签名,见附录1
                jsApiList: [
                  "onMenuShareTimeline",
                  "onMenuShareAppMessage", //1.0分享到朋友圈
                  "updateAppMessageShareData", //1.4 分享到朋友
                  "updateTimelineShareData"
                ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
              });
            } else {
              this.$toast(message);
            }
          },
          wxShare() {
            wx.ready(() => {
              let shareData = {
                title: this.detail.share_title,
                desc: this.detail.share_subtitle, //这里请特别注意是要去除html
                link: this.detail.share_info.share_url,
                imgUrl: this.detail.share_image ||
                  "http://youya.chuncom.com/youya-h5/img/logo.png"
              };
              if (wx.onMenuShareAppMessage) {
                //微信文档中提到这两个接口即将弃用,故判断
                wx.onMenuShareAppMessage(shareData); //1.0 分享到朋友
                wx.onMenuShareTimeline(shareData); //1.0分享到朋友圈
              } else {
                wx.updateAppMessageShareData(shareData); //1.4 分享到朋友
                wx.updateTimelineShareData(shareData); //1.4分享到朋友圈
              }
              wx.error(function(res) {
                // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
                // alert("errorMSG:" + res)
                window.console.log("errorMSG:" + res);
              });
            });
          },
          // 购买事件
          async buying() {
            let {
              code,
              data,
              message
            } = await window.axios.get("/user");
            if (code == 0) {
              this.userInfo = data;
              if (data.is_bind == 0) {
                this.$dialog
                  .confirm({
                    title: "提示",
                    message: "您还未绑定手机号,是否前往绑定?"
                  })
                  .then(() => {
                    this.$router.push({
                      name: "binding_information"
                    });
                  })
                  .catch(e => {
                    window.console.log(e);
                  });
                return;
              } else {
                this.$router.push({
                  name: "upgrade_create",
                  query: {
                    id: this.$route.query.id,
                    share_id: this.$route.query.share_id || ""
                  }
                });
              }
            } else if (code == 401) {
              this.$dialog
                .confirm({
                  title: "提示",
                  message: "您还未授权登录,无法进行购买,是否前往授权?"
                })
                .then(() => {
                  window.location.href = `http://youya.chuncom.com/user/authorization?url=${encodeURIComponent(
                  window.location.href
                )}`;
                })
                .catch(e => {
                  window.console.log(e);
                });
            }
          },
          async getData() {
            this.$toast.loading({
              message: "加载中..."
            });
            let {
              code,
              data,
              message
            } = await window.axios.get(
              "/user/upgrade/info", {
                params: {
                  info_id: this.$route.query.id
                }
              }
            );
            if (code == 0) {
              this.$toast.clear();
              this.detail = data;
              this.compoundImg();
              this.wxShare();
            } else {
              this.$toast.fail(message);
              // this.$router.push({ path: "/" });
            }
          },
          async compoundImg() {
            let {
              poster,
              image,
              share_info,
              name
            } = this.detail;
            // window.console.log(poster, image, share_info);
            let mc = new MCanvas({
               750,
              height: 1334,
              backgroundColor: "white"
            });
            // 海报背景图 this.list[this.active].image ../img/poster-psd.jpg
            mc.background(poster, {
                left: 0,
                top: 0,
                color: "#000000",
                type: "crop"
              })
              // 模板背景图连接
              // .add("../img/poster-bg.pn
              // hg",{
              //     610,
              //     height:642,
              //     pos:{
              //         x:70,
              //         y:160,
              //         scale:1
              //     },
              // })
              // 二维码连接 this.createShareImage.share_qr ../img/erweima.png
              .add(share_info.share_qr, {
                 126,
                height: 126,
                pos: {
                  x: 110,
                  y: 635,
                  scale: 1
                }
              })
              // 产品图连接 this.detail.image ../img/banner2-01.png
              .add(image, {
                 570,
                height: 321,
                pos: {
                  x: 90,
                  y: 180,
                  scale: 1
                }
              })
              .add("/youya-h5/img/logo.png", {
                 162,
                height: 168,
                pos: {
                  x: 487,
                  y: 620,
                  scale: 1
                }
              })
              // text 添加文字数据基础函数;
              .text(name, {
                 530,
                align: "left",
                normalStyle: {
                  font: `30px Microsoft YaHei,sans-serif`,
                  lineHeight: 32
                },
                pos: {
                  x: 110,
                  y: 525
                }
              })
              // text 添加文字数据基础函数;
              .text("加入学习", {
                 96,
                align: "left",
                normalStyle: {
                  font: `24px Microsoft YaHei,sans-serif`,
                  lineHeight: 28,
                  color: "#999"
                },
                pos: {
                  x: 254,
                  y: 660
                }
              })
              // text 添加文字数据基础函数;
              .text("长按识别二维码", {
                 168,
                align: "left",
                normalStyle: {
                  font: `24px Microsoft YaHei,sans-serif`,
                  lineHeight: 28,
                  color: "#999"
                },
                pos: {
                  x: 254,
                  y: 708
                }
              })
              .draw(b64 => {
                window.console.log(b64);
                this.imgUrl = b64;
              });
          }
        },
        created() {
          this.add();
          this.getData();
          this.getSDK();
        },
        mounted() {}
      };
    </script>
    <style lang="less">
      .live-banner {
         100%;
      }
    
      .course-info {
        flex: 1;
      }
    
      .course-share {
        position: relative;
         84px;
        padding-top: 10px;
    
        img {
           24px;
          height: 24px;
        }
    
        .award-tips {
          position: absolute;
          top: 0;
          right: -5px;
          padding: 2px 4px;
          font-size: 10px;
          color: #fff;
          background: linear-gradient(141deg,
              rgba(252, 186, 133, 1) 0%,
              rgba(255, 169, 117, 1) 100%);
          border-radius: 11px 11px 11px 0;
        }
      }
    
      .footer-bar {
        box-shadow: 0px 0px 5px 0px rgba(238, 238, 238, 1);
      }
    
      .btn-youya {
         260px;
        height: 40px;
        line-height: 40px;
        background: linear-gradient(143deg,
            rgba(157, 195, 230, 1) 0%,
            rgba(131, 179, 219, 1) 100%);
        border-radius: 20px;
        color: #fff;
        font-size: 15px;
        text-align: center;
        box-shadow: 1px 5px 6px rgba(131, 179, 219, 0.2);
    
        &.disable {
          background: #cccccc;
          box-shadow: none;
        }
      }
    
      .back-home {
         90px;
        text-align: center;
    
        img {
          display: inline-block;
           24px;
          height: 24px;
        }
      }
    
      .catalogue-list {
        padding: 15px;
    
        .catalogue-item {
          display: flex;
          margin-bottom: 15px;
          align-items: center;
    
          .thumb {
            position: relative;
             90px;
            height: 50px;
            background-position: center;
            background-size: contain;
            background-repeat: no-repeat;
            border-radius: 5px;
    
            .duration {
              position: absolute;
              right: 7px;
              bottom: 2px;
              font-size: 11px;
              color: #fff;
            }
          }
    
          .tilte {
            margin-left: 10px;
            flex: 1;
          }
        }
      }
    
      .side-btn {
        position: fixed;
        top: 60%;
        right: 5px;
    
        img {
           45px;
          height: 45px;
        }
      }
    
      .poster {
         80vw;
      }
    
      .xieyi-box {
        padding: 0 20px;
         310px;
        height: 395px;
        background: rgba(255, 255, 255, 1);
        border-radius: 8px;
        box-sizing: border-box;
    
        .title {
          padding: 25px 0;
          font-size: 18px;
          color: #333;
          text-align: center;
        }
    
        .content-box {
          margin-bottom: 10px;
          height: 260px;
          overflow-y: scroll;
        }
    
        .btns {
          display: flex;
          justify-content: space-around;
    
          .btn {
             105px;
            height: 35px;
            line-height: 35px;
            background: linear-gradient(143deg,
                rgba(157, 195, 230, 1) 0%,
                rgba(131, 179, 219, 1) 100%);
            border-radius: 18px;
            text-align: center;
            font-size: 13px;
            color: #fff;
    
            &.disable {
              opacity: 0.5;
            }
          }
    
          .btn-o {
             105px;
            height: 35px;
            line-height: 35px;
            border-radius: 18px;
            border: 1px solid rgba(204, 204, 204, 1);
            text-align: center;
            font-size: 13px;
            color: #999999;
          }
        }
      }
    
      .checked {
        position: relative;
        margin-right: 10px;
         15px;
        height: 15px;
        border: 1px solid rgba(153, 153, 153, 1);
        border-radius: 50%;
    
        &.on {
          border-color: #8db9df;
        }
    
        &.on::after {
          content: " ";
          position: absolute;
          left: 50%;
          top: 50%;
           10px;
          height: 10px;
          background-color: #8db9df;
          border-radius: 50%;
          transform: translate(-50%, -50%);
        }
      }
    </style>
    

    后记东西太多了

  • 相关阅读:
    python之字典
    Python包管理工具
    【转】Python实现修改Windows CMD命令行输出颜色(完全解析)
    进程池中传递实例方法问题
    HTML协议详解
    【转】python数据格式化之pprint
    【转】Python装饰器与面向切面编程
    【转】TCP/IP报文格式
    python之线程学习
    python之面向对象
  • 原文地址:https://www.cnblogs.com/smart-girl/p/12878169.html
Copyright © 2011-2022 走看看