这是一个比较大的项目哦
先放上作者的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>
后记东西太多了