levels of contents

Vue项目搭建

1. 项目分析

首页
	导航、登录注册栏、轮播图、地板导航
登录注册
	选项卡
免费课
	课程分类、筛选、课程列表
免费课详情
	课程封面视频、优惠活动倒计时、选项卡
我的购物车
	全选、商品价格统计
购买结算
	
购买成功
	
我的订单
	
课时播放页面
	

2. 项目搭建

2.1 创建项目目录

cd 项目目录
vue init webpack luffy

例如,我要把项目保存在桌面下 ~/Desktop/luffy ,可以如下操作:

cd Desktop
vue init webpack luffy

效果:

1556413886156

根据需要在生成项目时,我们选择对应的选项。

1556413914975

根据上面的提示,我们已经把vue项目构建好了,接下来我们可以在pycharm编辑器中把项目打开并根据上面黄色提示,运行测试服务器。

1556413966065

打开项目已经,在pycharm的终端下运行vue项目,查看效果。

npm run dev

1556414060937

接下来,我们根据终端上效果显示的对应地址来访问项目(如果有多个vue项目在运行,8080端口被占据了,服务器会自动改端口,所以根据自己实际在操作中看到的地址来访问。)

访问:http://localost:8080

1552440150350

2.2 初始化项目

清除默认的HelloWorld.vue组件和APP.vue中的默认模板代码和默认样式

1556414352611

<template>
  <div id="app">
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
  }
}
</script>

<style>
</style>

修改后效果:

1552458440851

接下来,我们可以查看效果了,一张白纸~

1556414476287

2.3 安装路由vue-router

2.3.1 下载路由组件

npm i vue-router -S

执行效果:

1556414629058

2.3.2 配置路由

2.3.2.1 初始化路由对象

在src目录下创建router路由目录,在router目录下创建index.js路由文件

效果:

1556415543613

index.js路由文件中,编写初始化路由对象的代码 .

import Vue from "vue"
import Router from "vue-router"

// 这里导入可以让让用户访问的组件

Vue.use(Router);

export default new Router({
  // 设置路由模式为‘history’,去掉默认的#
  mode: "history",
  routes:[
    // 路由列表

  ]
})

2.3.2.2 注册路由信息

打开main.js文件,把router路由规则对象注册到vue中.

1556415594925

代码:

// 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 App from './App'
import router from './router/index';

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
});

2.3.2.3 在视图中显示路由对应的内容

在App.vue组件中,添加显示路由对应的内容。

1556415832883

代码:

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>


3. 引入ElementUI

对于前端页面布局,我们可以使用一些开源的UI框架来配合开发,Vue开发前端项目中,比较常用的就是ElementUI了。

ElementUI是饿了么团队开发的一个UI组件框架,这个框架提前帮我们提供了很多已经写好的通用模块,我们可以在Vue项目中引入来使用,这个框架的使用类似于我们前面学习的bootstrap框架,也就是说,我们完全可以把官方文档中的组件代码拿来就用,有定制性的内容,可以直接通过样式进行覆盖修改就可以了。

1552501300174

中文官网:http://element-cn.eleme.io/#/zh-CN

文档快速入门:http://element-cn.eleme.io/#/zh-CN/component/quickstart

3.1 快速安装ElementUI

项目根目录执行以下命令:

npm i element-ui -S

上面的命令等同于 npm install element-ui --save

执行命令效果:

1556417812874

3.2 配置ElementUI到项目中

在main.js中导入ElementUI,并调用。代码:

// elementUI 导入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 调用插件
Vue.use(ElementUI);

效果:

1552501156871

成功引入了ElementUI以后,接下来我们就可以开始进入前端页面开发,首先是首页。

4. 首页

首页采用了上下页面布局,首页是导航栏、轮播图。。。脚部等几个小模块。所以我们可以把首页作为一个组件进行开发,然后把首页的这些小模块作为单独的组件来进行开发。

4.1 创建首页组件

在src/components目录下创建文件 Home.vue

代码:

<template>
  <div id="home">
    首页
  </div>
</template>

<script>
export default {
  name:"Home",
  data(){
    return {

    }
  }
}
</script>

<style scoped>

</style>


效果:

1556415917941

4.1.1 创建首页对应的路由

在router/index.js中引入Home组件,并设置Home组件作为首页路由。

代码:

import Vue from "vue"
import Router from "vue-router"

// 后面这里引入可以被用户访问的页面组件
import Home from "../components/Home"

Vue.use(Router);

export default new Router({
  // 路由跳转模式,注意使用 history
  mode: "history",

  // 路由规则
  routes:[
    {
      // name:"路由别名",
      name:"Home",
      // path: "路由地址",
      path: "/",
      // component: 组件类名,
      component: Home,
    },{
      // name:"路由别名",
      name:"Home",
      // path: "路由地址",
      path: "/home",
      // component: 组件类名,
      component: Home,
    },
  ]
})


效果:

1556416079117

4.2 开发导航子组件

经过前面的观察,可以发现导航不仅在首页出现,其他页面也有,所以对于这些不同页面中公共的内容,可以创建一个单独的组件目录存放。

1552501540495

创建src/components/common/Header.vue目录路径,编写代码:

<template>

</template>

<script>
  export default {
    name: "Header",
    data(){
      return {
        
      };
    }
  }
</script>

<style scoped>

</style>

效果:

1552501465055

4.2.1 在首页引入导航组件

代码:

<template>
  <div class="home">
    <Header/>
  </div>
</template>

<script>
  import Header from "./common/Header"
  export default {
    name: "Home",
    data(){
      return {

      };
    },
    components:{
      Header,
    }
  }
</script>

<style scoped>

</style>


效果:

1552502367059

接下来,我们就可以在组件中参考ElementUI文档来进行样式开发了。

1552503046597

Header的子组件代码:

<template>
  <div class="header">
    <el-container>
      <el-header>
        <el-row>
          <el-col class="logo" :span="3">
            <a href="/">
              <img src="@/assets/head-logo.svg" alt="">
            </a>
          </el-col>
          <el-col class="nav" :span="16">
              <el-row>
                <el-col :span="3"><router-link to="/">免费课</router-link></el-col>
                <el-col :span="3"><router-link to="/">轻课</router-link></el-col>
                <el-col :span="3"><router-link to="/">学位课</router-link></el-col>
                <el-col :span="3"><router-link to="/">题库</router-link></el-col>
                <el-col :span="3"><router-link to="/">教育</router-link></el-col>
              </el-row>
          </el-col>
          <el-col class="login-bar" :span="5">
            <el-row>
              <el-col class="cart-ico" :span="9">
                <router-link to="">
                  <b class="goods-number">0</b>
                  <img class="cart-icon" src="@/assets/cart.svg" alt="">
                  <span>购物车</span>
                </router-link>
              </el-col>
              <el-col class="study" :span="8" :offset="2"><router-link to="">学习中心</router-link></el-col>
              <el-col class="member" :span="5">
                <el-menu class="el-menu-demo" mode="horizontal">
                  <el-submenu index="2">
                    <template slot="title"><router-link to=""><img src="@/assets/logo@2x.png" alt=""></router-link></template>
                    <el-menu-item index="2-1">我的账户</el-menu-item>
                    <el-menu-item index="2-2">我的订单</el-menu-item>
                    <el-menu-item index="2-3">我的优惠卷</el-menu-item>
                    <el-menu-item index="2-3">退出登录</el-menu-item>
                  </el-submenu>
                </el-menu>
              </el-col>
            </el-row>
          </el-col>
        </el-row>
      </el-header>
    </el-container>
  </div>
</template>

<script>
  export default {
    name: "Header",
    data(){
      return {
        // 设置一个登录标识,表示是否登录
        token: false,
      };
    }
  }
</script>

<style scoped>
  .header{
    box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
  }
  .header .el-container{
    width: 1200px;
    margin: 0 auto;
  }
  .el-header{
    height: 80px!important;
    padding:0;
  }
  .logo{

  }
  .logo img{
    padding-top: 22px;
  }

  .nav{
    margin-top: 22px;
  }

  .nav .el-col a{
    display: block;
    text-align: center;
    padding-bottom: 16px;
    padding-left: 5px;
    padding-right: 5px;
    position: relative;
    font-size: 16px;
  }

  .login-bar{
    margin-top: 22px;
  }
  .cart-ico{
    position: relative;
    border-radius: 17px;
  }
  .cart-ico:hover{
    background: #f0f0f0;
  }
  .goods-number{
    width: 16px;
    height: 16px;
    line-height: 17px;
    font-size: 12px;
    color: #fff;
    text-align: center;
    background: #fa6240;
    border-radius: 50%;
    transform: scale(.8);
    position: absolute;
    left: 16px;
    top: -1px;
  }
  .cart-icon{
    width: 15px;
    height: auto;
    margin-left: 6px;
  }
  .cart-ico span{
    margin-left: 12px;
  }
  .member img{
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: inline-block;
  }
  .member img:hover{
    border: 1px solid yellow;
  }

</style>


App.vue,中设置一些公共样式的代码:

<style>
  body{
    padding: 0;
    margin:0;
  }
  a{
    text-decoration: none;
    color: #4a4a4a;
  }
  a:hover{
    color: #000;
  }
  .header .el-menu li .el-submenu__title{
    height: 26px!important;
    line-height: 26px!important;
  }
  .el-menu--popup{
    min-width: 140px;
  }
</style>

Home组件中引入使用Header子组件,代码无需改变,直接访问效果:

1556423948867

4.3 开发轮播图子组件

1552503138518

4.3.1 创建Banner.vue组件文件

代码:

<template>
  <div class="banner">

  </div>
</template>

<script>
  export default {
    name:"Banner",
    data(){
      return {};
    }
  }
</script>

<style scoped>

</style>


1552532166152

4.3.1 在Home组件中引入Banner子组件

<template>
  <div class="home">
    <Header/>
    <Banner/>
  </div>
</template>

<script>
  import Header from "./common/Header"
  import Banner from "./common/Banner"
  export default{
    name:"Home",
    data(){
      return {};
    },
    components:{
      Header,
      Banner,
    }
  }
</script>

<style scoped>
.home{
  padding-top: 80px;
}
</style>


效果:

1552532278649

接下来,在ElementUI中有对应的轮播图[跑马灯]效果,可以直接提取过来使用。

1556424098873

注意,图片保存到static目录下。保存在assets目录下的图片等同于保存在static/img目录下。

1556424903235

对于图片的使用,如果是vue代码中直接要使用的图片,可以保存accets目录下,如果是第三方插件要使用到的图片,需要保存在static目录下。其实本质上来说,所有的图片都是保存在static目录下的,而assets目录下的内容,最终被vue解析成地址的时候,也是在static目录的.

Banner.vue组件,代码:

<template>
  <div class="banner">
      <el-carousel trigger="click" height="506px">
        <el-carousel-item v-for="banner in banner_list">
          <a :href="banner.link"><img width="100%" :src="banner.img" alt=""></a>
        </el-carousel-item>
      </el-carousel>
  </div>
</template>

<script>
  export default {
    name:"Banner",
    data(){
      return {
        banner_list:[
          {link:"http://www.baidu.com",img:"/static/banner/1.png"},
          {link:"http://www.baidu.com",img:"/static/banner/2.png"},
          {link:"http://www.baidu.com",img:"/static/banner/3.png"},
        ]
      };
    }
  }
</script>

<style scoped>

</style>


效果:

1552533179082

4.5 页面脚部

4.5.1 创建脚部组件文件

1552535310891

代码:

<template>
  <el-container>

  </el-container>
</template>

<script>
  export default {
    name:"Footer",
    data(){
      return {}
    }
  }
</script>


<style scoped>

</style>


4.5.2 在Home组件中引入Footer组件

Home组件代码:

<template>
  <div class="home">
    <Header/>
    <Banner/>
    <Footer/>
  </div>
</template>

<script>
  import Header from "./common/Header"
  import Banner from "./common/Banner"
  import Footer from "./common/Footer"
  export default{
    name:"Home",
    data(){
      return {};
    },
    components:{
      Header,
      Banner,
      Footer,
    }
  }
</script>

<style scoped>
.home{
  padding-top: 80px;
}
</style>


效果:

1552535407021

4.5.3 编写脚部样式

<template>
  <div class="footer">
    <el-container>
      <el-row>
        <el-col :span="4"><router-link to="">关于我们</router-link></el-col>
        <el-col :span="4"><router-link to="">联系我们</router-link></el-col>
        <el-col :span="4"><router-link to="">商务合作</router-link></el-col>
        <el-col :span="4"><router-link to="">帮助中心</router-link></el-col>
        <el-col :span="4"><router-link to="">意见反馈</router-link></el-col>
        <el-col :span="4"><router-link to="">新手指南</router-link></el-col>
        <el-col :span="24"><p class="copyright">Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p></el-col>
      </el-row>
    </el-container>
  </div>
</template>

<script>
  export default {
    name:"Footer",
    data(){
      return {}
    }
  }
</script>


<style scoped>
.footer{
  width: 100%;
  height: 128px;
  background: #25292e;
}
.footer .el-container{
  width: 1200px;
  margin: auto;
}
.footer .el-row {
  align-items: center;
  padding: 0 200px;
  padding-bottom: 15px;
  width: 100%;
  margin-top: 38px;
}
.footer .el-row a{
  color: #fff;
  font-size: 14px;
}
.footer .el-row .copyright{
  text-align: center;
  color: #fff;
  font-size: 14px;
}
</style>


效果:

1556425996044

首页的三大块我们已经完成了,但是我们开始新的页面出现之前,我们需要把链接补充上, 新增课程的导航链接.

接下来,我们就可以创建免费课的组件.

4.6 固定头部

App.vue

<style>
  body{
    padding: 0;
    margin:0;
    margin-top: 80px;
  }
  
</style>

Header.vue,代码:

<style scoped>
  .header{
    top:0;
    left:0;
    right:0;
    margin: auto;
    background-color: #fff;
    height: 80px;
    z-index: 1000;
    position: fixed;
    box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
  }

</style>


调整轮播图左右两边的按钮

注意,style标签中要设置全局样式,所以不需要scoped

Banner.vue

<style>
.el-carousel__arrow{
  width: 100px!important;
  height: 100px!important;
}
.el-icon-arrow-left{
  font-size: 35px;
  margin-left: 50px;
}
.el-carousel__arrow--left{
  left: -50px;
}
</style>

5. 免费课

在组件目录components下创建Course.vue组件文件,代码如下:

<template>
  <div class="course">

  </div>
</template>

<script>
export default {
  name: "Course",
  data(){
    return {

    }
  },
}
</script>


<style scoped>
  
</style>


5.1 在routers/index.js路由中注册路由

import Vue from "vue"
import Router from "vue-router"

// 导入可以被用户访问的组件
import Home from "@/components/Home"
import Course from "@/components/Course"

Vue.use(Router);

export default new Router({
  mode: "history",
  routes:[
    // 路由列表
    {
      path: "/",
      name: "Home",
      component:Home,
    },
    {
      path: "/home",
      name: "Home",
      component:Home,
    },
    {
      path: "/course",
      name: "Course",
      component:Course,
    },

  ]
})


5.2 完成免费课课程列表

5.2.2 文件代码结构

Course.vue,代码:

<template>
  <div class="course">
    <Header/>
    <div class="main">
      <!-- 筛选功能 -->
      <div class="top">

      </div>
      <!-- 课程列表 --->
      <div class="list">

      </div>
    </div>
    <Footer/>
  </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
  name: "Course",
  data(){
    return {

    }
  },
  components:{Header,Footer}
}
</script>

<style scoped>

</style>

5.2.3 筛选条件的样式实现

<template>
  <div class="courses">
    <Header/>
    <div class="main">
      <!--filter function-->
      <div class="top">
        <ul class="condition condition1">
          <li class="cate-condition">课程分类</li>
          <li class="item current">全部</li>
          <li class="item">Python</li>
          <li class="item">Linux运维</li>
          <li class="item">开发工具</li>
          <li class="item">Go语言</li>
          <li class="item">机器学习</li>
          <li class="item">技术生涯</li>
        </ul>
        <ul class="condition condition2">
          <li class="cate-condition">筛&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;选</li>
          <li class="item current">默认</li>
          <li class="item">人气</li>
          <li class="item price">价格</li>
          <li class="courses-length">共21个课程</li>
        </ul>
      </div>
      
      
      <!--courses list-->
      <div class="list">
      </div>
    </div>
    <Footer/>
  </div>
</template>


<script>
  import Header from "./common/Header"
  import Footer from "./common/Footer"


  export default{
    name: "Courses",
    data(){
      return {}},
    components:{
      Header,
      Footer,
    },
    methods:{}
  }
</script>


<style scoped>
  .main{
    width: 1100px;
    height: auto;
    margin: 0 auto;
    padding-top: 35px;
  }
  .main .top{
    margin-bottom: 35px;
    padding: 25px 30px 25px 20px;
    background: #ffffff;
    border-radius: 4px;
    box-shadow: 0 2px 4px 0 #f0f0f0;
  }
  .condition{
    border-bottom: 1px solid #333333;
    border-bottom-color: rgba(51, 51, 51, .05);
    padding-bottom: 18px;
    margin-bottom: 17px;
    overflow: hidden;
  }
  .condition li{
    float: left;
  }
  .condition .cate-condition{
    color: #888888;
    font-size: 16px;
  }
  .condition .item{
    padding: 6px 16px;
    line-height: 16px;
    margin-left: 14px;
    position: relative;
    transition: all .3s ease;
    cursor: pointer;
    color: #4a4a4a;
  }
  .condition1 .current{
    color: #ffc210;
    border: 1px solid #ffc210!important;
    border-radius: 30px;
  }
  .condition2 .current{
    color: #ffc210;
  }
  .condition .price::before{
    content: "";
    width: 0;
    border: 5px solid transparent;
    border-top-color: #ffc210;
    position: absolute;
    right: 0;
    bottom: 2.5px;
  }
  .condition .price::after{
  content: "";
    width: 0;
    border: 5px solid transparent;
    border-bottom-color: #d8d8d8;
    position: absolute;
    right: 0;
    top: 2.5px;
  }
  .condition2 .courses-length{
    float: right;
    font-size: 14px;
    color: #9b9b9b;
  }

</style>


App.vue针对列表标签进行初始化,代码:

ul{
    list-style: none;
    padding:0;
    margin:0;
  }
  

效果:

1556502578181

5.2.4 课程类表的样式实现和特效

<template>
  <div class="courses">
    <Header/>
    <div class="main">
      <!--filter function-->
      <div class="top">
        <ul class="condition condition1">
          <li class="cate-condition">课程分类</li>
          <li class="item current">全部</li>
          <li class="item">Python</li>
          <li class="item">Linux运维</li>
          <li class="item">开发工具</li>
          <li class="item">Go语言</li>
          <li class="item">机器学习</li>
          <li class="item">技术生涯</li>
        </ul>
        <ul class="condition condition2">
          <li class="cate-condition">筛&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;选</li>
          <li class="item current">默认</li>
          <li class="item">人气</li>
          <li class="item price">价格</li>
          <li class="courses-length">共21个课程</li>
        </ul>
      </div>


      <!--courses list-->
      <div class="list">
        <ul>
          <li class="course-item">
            <div class="course-cover">
              <img src="../../static/courses/1.jpeg" alt=""/>
            </div>
            <div class="course-info">
              <div class="course-title">
                <h3>Python开发21天入门</h3>
                <span>69939人已经加入学习</span>
              </div>
              <p class="teacher">
                <span class="info">Alex 金角大王 老男孩Python教学总监</span>
                <span class="lesson">共154课时/更新完成</span>
              </p>
              <ul class="lesson-list">
                <li>
                  <p class="lesson-title">01 | 常用模块学习-模块的种类和导入方法</p>
                  <span class="free">免费</span>
                </li>
                 <li>
                  <p class="lesson-title">02 | 编程语言介绍(三)高级语言</p>
                  <span class="free">免费</span>
                </li>
                 <li>
                  <p class="lesson-title">03 | 编程语言介绍(一)</p>
                  <span class="free">免费</span>
                </li>
                 <li>
                  <p class="lesson-title">04 | 课程介绍(二)-Python与其他语言的区别</p>
                  <span class="free">免费</span>
                </li>
              </ul>
              <div class="buy-info">
                <span class="discount">限时免费</span>
                <span class="present-price">¥0.00元</span>
                <span class="original-price">原价:9.00元</span>
                <span class="buy-now">立即购买</span>
              </div>
            </div>
          </li>
        </ul>
      </div>
    </div>
    <Footer/>
  </div>
</template>


<script>
  import Header from "./common/Header"
  import Footer from "./common/Footer"


  export default{
    name: "Courses",
    data(){
      return {}},
    components:{
      Header,
      Footer,
    },
    methods:{}
  }
</script>


<style scoped>
  .main{
    width: 1100px;
    height: auto;
    margin: 0 auto;
    padding-top: 35px;
  }
  .main .top{
    margin-bottom: 35px;
    padding: 25px 30px 25px 20px;
    background: #ffffff;
    border-radius: 4px;
    box-shadow: 0 2px 4px 0 #f0f0f0;
  }
  .condition{
    border-bottom: 1px solid #333333;
    border-bottom-color: rgba(51, 51, 51, .05);
    padding-bottom: 18px;
    margin-bottom: 17px;
    overflow: hidden;
  }
  .condition li{
    float: left;
  }
  .condition .cate-condition{
    color: #888888;
    font-size: 16px;
  }
  .condition .item{
    padding: 6px 16px;
    line-height: 16px;
    margin-left: 14px;
    position: relative;
    transition: all .3s ease;
    cursor: pointer;
    color: #4a4a4a;
  }
  .condition1 .current{
    color: #ffc210;
    border: 1px solid #ffc210!important;
    border-radius: 30px;
  }
  .condition2 .current{
    color: #ffc210;
  }
  .condition .price::before{
    content: "";
    width: 0;
    border: 5px solid transparent;
    border-top-color: #ffc210;
    position: absolute;
    right: 0;
    bottom: 2.5px;
  }
  .condition .price::after{
  content: "";
    width: 0;
    border: 5px solid transparent;
    border-bottom-color: #d8d8d8;
    position: absolute;
    right: 0;
    top: 2.5px;
  }
  .condition2 .courses-length{
    float: right;
    font-size: 14px;
    color: #9b9b9b;
  }


  .course-item{
    background: #ffffff;
    padding: 20px 30px 20px 20px;
    margin-bottom: 35px;
    border-radius: 2px;
    cursor: pointer;
    box-shadow: 2px 3px 16px rgba(0, 0, 0, .1);
    transition: all .2s ease;
    overflow: hidden;
  }
  .course-cover{
    width: 423px;
    height: 210px;
    margin-right: 30px;
    float: left;
  }
  .course-info{
    width: 597px;
    float: left;
  }
  .course-title{
    margin-bottom: 8px;
    overflow: hidden;
  }
  .course-title h3{
    font-size: 26px;
    color: #333333;
    float: left;
  }
  .course-title span{
    float: right;
    font-size: 14px;
    color: #9b9b9b;
    margin-top: 12px;
    text-indent: 1em;
    background: url("../assets/people.svg") no-repeat 0px 3px;
  }
  .teacher{
    justify-content: space-between;
    font-size: 14px;
    color: #9b9b9b;
    margin-bottom: 14px;
    padding-bottom: 14px;
    border-bottom: 1px solid #333333;
    border-bottom-color: rgba(51, 51, 51, .05);
  }
  .teacher .lesson{
    float: right;
  }
  .lesson-list{
    overflow: hidden;
  }
  .lesson-list li{
    width: 49%;
    margin-bottom: 15px;
    cursor: pointer;
    float: left;
    margin-right: 1%;
  }
  .lesson-list li .player{
    width: 16px;
    height: 16px;
    vertical-align: text-bottom;
  }
  .lesson-list li .lesson-title{
    display: inline-block;
    max-width: 227px;
    text-overflow: ellipsis;
    color: #666666;
    overflow: hidden;
    white-space: nowrap;
    font-size: 14px;
    vertical-align: text-bottom;
    text-indent: 1.5em;
    background: url("../../static/2.svg") no-repeat 0px 3px;
  }
  .lesson-list .free{
    width: 34px;
    height: 20px;
    color: #fd7b4d;
    margin-left: 10px;
    border-radius: 2px;
    border: 1px solid #fd7b4d;
    text-align: center;
    font-size: 13px;
    white-space: nowrap;
  }

.lesson-list li:hover .lesson-title{
    color: #ffc210;
    background-image: url(../../static/2.svg);
}
.lesson-list li:hover .free{
    border-color: #ffc210;
    color: #ffc210;
}

.buy-info .discount{
    padding: 0px 10px;
    font-size: 16px;
    color: #fff;
    display: inline-block;
    height: 36px;
    text-align: center;
    margin-right: 8px;
    background: #fa6240;
    border: 1px solid #fa6240;
    border-radius: 10px 0 10px 0;
    line-height: 36px;
}
.present-price{
    font-size: 24px;
    color: #fa6240;
}
.original-price{
    text-decoration: line-through;
    font-size: 14px;
    color: #9b9b9b;
    margin-left: 10px;
}
.buy-now{
    width: 120px;
    height: 38px;
    background: transparent;
    color: #fa6240;
    font-size: 16px;
    border: 1px solid #fd7b4d;
    border-radius: 3px;
    transition: all .2s ease-in-out; /* 过渡动画 */
    float: right;
    margin-top: 5px;
}
.buy-now:hover{
    color: #fff;
    background: #ffc210;
    border: 1px solid #ffc210;
    cursor: pointer;
}
</style>

App.vue

<style>
  body,h3,ul,p{
    padding: 0;
    margin:0;
    font-weight: normal;
  }
  body{
    margin-top: 80px;
  }
  a{
    text-decoration: none;
    color: #4a4a4a;
  }
  a:hover{
    color: #000;
  }

  ul{
    list-style: none;
  }

  img{
    width: 100%;
  }

  .header .el-menu li .el-submenu__title{
    height: 26px!important;
    line-height: 26px!important;
  }
  .el-menu--popup{
    min-width: 140px;
  }

</style>

6. 针对页面头部部分增加高亮和登录按钮

6.1 增加当前页面导航高亮效果

<template>
<div class="header">
  <el-container>
    <el-header>
      <el-row>
        <el-col class="logo" :span="3">
          <img src="@/assets/head-logo.svg" alt=""/>
        </el-col>
        <el-col class="nav" :span="16">
          <el-row>
            <!-- 加入current 实现高亮效果 -->
            <el-col :span="3"><router-link class="current" to="/home">免费课</router-link></el-col>
            <el-col :span="3"><router-link to="/">轻课</router-link></el-col>
            <el-col :span="3"><router-link to="/">学位课</router-link></el-col>
            <el-col :span="3"><router-link to="/">题库</router-link></el-col>
            <el-col :span="3"><router-link to="/">教育</router-link></el-col>
          </el-row>
        </el-col>
        <el-col class="login-bar" :span="5">
          <el-row>
            <el-col class="cart-ico" :span="9">
              <router-link to="">
              <b class="goods-number">0</b>
              <img class="cart-icon" src="@/assets/download.svg" alt=""/>
              <span>购物车</span>
              </router-link>
            </el-col>
            <el-col class="study" :span="8" :offset="2"><router-link to="">学习中心</router-link></el-col>
            <el-col class="member" :span="5">
              <el-menu class="el-menu-demo" mode="horizontal">
                <el-submenu index="2">
                  <template slot="title"><router-link to=""><img src="@/assets/logo@2x.png" alt=""/></router-link></template>
                  <el-menu-item index="2-1">我的账户</el-menu-item>
                  <el-menu-item index="2-2">我的订单</el-menu-item>
                  <el-menu-item index="2-3">我的优惠券</el-menu-item>
                  <el-menu-item index="2-4">退出登录</el-menu-item>
                </el-submenu>
              </el-menu>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
    </el-header>
  </el-container>
</div>
</template>

<script>
  export default {
    name: "Header",
    data(){
      return {};
    }
  }
</script>

<style scoped>
  .header{
    top: 0;
    left: 0;
    right: 0;
    margin: auto;
    background-color: #ffffff;
    height: 80px;
    z-index: 1000;
    position: fixed;
    width: 100%;
    box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
  }
  .header .el-container{
    width: 1200px;
    margin: 0 auto;
  }
  .el-header{
    height: 80px!important;
    padding: 0;
  }
  .logo img{
    padding-top: 17px;
  }
  .nav{
    margin-top: 22px;
  }
  .nav .el-col a{
    display: block;
    text-align: center;
    margin-left: 30px;
    padding-bottom: 16px;
    padding-left: 5px;
    padding-right: 5px;
    position: relative;
    font-size: 16px;
    text-decoration: none;
  }
  /* 加入current实现高亮效果 */
  .nav .el-col .current{
    color: #4a4a4a;
    border-bottom: 4px solid #ffc210;
  }
  .login-bar{
    margin-top: 22px;
  }
  .cart-ico{
    position: relative;
    border-radius: 17px;
  }
  .cart-ico:hover{
    background: #f0f0f0;
  }
  .goods-number{
    width: 16px;
    height: 16px;
    line-height: 17px;
    font-size: 12px;
    color: #ffffff;
    text-align: center;
    background: #fa6240;
    border-radius: 50%;
    transform: scale(.8);
    position: absolute;
    left: 16px;
    top: -1px;
  }
  .cart-icon{
    width: 15px;
    height: auto;
    margin-left: 6px;
  }
  .cart-ico span{
    margin-left: 12px;
  }
  .cart-ico a{
    text-decoration: none;
  }
  .member img{
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: inline-block;
  }
  .member img:hover{
    border: 1px solid yellow;
  }
  .study a{
    text-decoration: none;
  }
</style>

6.2 根据登录状态显示登录注册按钮

<template>
  <div class="header">
    <el-container>
      <el-header>
        <el-row>
          <el-col class="logo" :span="3">
            <a href="/">
              <img src="@/assets/head-logo.svg" alt="">
            </a>
          </el-col>
          <el-col class="nav" :span="16">
              <el-row>
                <el-col :span="3"><router-link class="current" to="/">免费课</router-link></el-col>
                <el-col :span="3"><router-link to="/">轻课</router-link></el-col>
                <el-col :span="3"><router-link to="/">学位课</router-link></el-col>
                <el-col :span="3"><router-link to="/">题库</router-link></el-col>
                <el-col :span="3"><router-link to="/">教育</router-link></el-col>
              </el-row>
          </el-col>
          <el-col class="login-bar" :span="5">
            <el-row v-if="token">
              <el-col class="cart-ico" :span="9">
                <router-link to="">
                  <b class="goods-number">0</b>
                  <img class="cart-icon" src="@/assets/cart.svg" alt="">
                  <span>购物车</span>
                </router-link>
              </el-col>
              <el-col class="study" :span="8" :offset="2"><router-link to="">学习中心</router-link></el-col>
              <el-col class="member" :span="5">
                <el-menu class="el-menu-demo" mode="horizontal">
                  <el-submenu index="2">
                    <template slot="title"><router-link to=""><img src="@/assets/logo@2x.png" alt=""></router-link></template>
                    <el-menu-item index="2-1">我的账户</el-menu-item>
                    <el-menu-item index="2-2">我的订单</el-menu-item>
                    <el-menu-item index="2-3">我的优惠卷</el-menu-item>
                    <el-menu-item index="2-3">退出登录</el-menu-item>
                  </el-submenu>
                </el-menu>
              </el-col>
            </el-row>
            <el-row v-else>
              <el-col class="cart-ico" :span="9">
                <router-link to="">
                  <img class="cart-icon" src="@/assets/cart.svg" alt="">
                  <span>购物车</span>
                </router-link>
              </el-col>
              <el-col :span="10" :offset="5">
                <span class="register">
                  <router-link to="/login">登录</router-link>
                  &nbsp;&nbsp;|&nbsp;&nbsp;
                  <router-link to="/register">注册</router-link>
                </span>
              </el-col>
            </el-row>
          </el-col>
        </el-row>
      </el-header>
    </el-container>
  </div>
</template>

<script>
  export default {
    name: "Header",
    data(){
      return {
        // 设置一个登录标识,表示是否登录
        token: false,
      };
    }
  }
</script>

<style scoped>
  .header{
    top:0;
    left:0;
    right:0;
    margin: auto;
    background-color: #fff;
    height: 80px;
    z-index: 1000;
    position: fixed;
    box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
  }
  .header .el-container{
    width: 1200px;
    margin: 0 auto;
  }
  .el-header{
    height: 80px!important;
    padding:0;
  }
  .logo{

  }
  .logo img{
    padding-top: 22px;
  }

  .nav{
    margin-top: 22px;
  }

  .nav .el-col a{
    display: inline-block;
    text-align: center;
    padding-bottom: 16px;
    padding-left: 5px;
    padding-right: 5px;
    position: relative;
    font-size: 16px;
    margin-left: 20px;
  }

  .nav .el-col .current{
    color: #4a4a4a;
    border-bottom: 4px solid #ffc210;
  }

  .login-bar{
    margin-top: 22px;
  }
  .cart-ico{
    position: relative;
    border-radius: 17px;
  }
  .cart-ico:hover{
    background: #f0f0f0;
  }
  .goods-number{
    width: 16px;
    height: 16px;
    line-height: 17px;
    font-size: 12px;
    color: #fff;
    text-align: center;
    background: #fa6240;
    border-radius: 50%;
    transform: scale(.8);
    position: absolute;
    left: 16px;
    top: -1px;
  }
  .cart-icon{
    width: 15px;
    height: auto;
    margin-left: 6px;
  }
  .cart-ico span{
    margin-left: 12px;
  }
  .member img{
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: inline-block;
  }
  .member img:hover{
    border: 1px solid yellow;
  }

</style>

data数据中使用token控制显示登录和未登录状态的效果:

token:false

1552660186604

token: true

1552660243916

7. 购物车页面

在头部公共组件中打通购物车的链接地址,Header.vue

<span><router-link to="/cart">购物车</router-link></span>

7.1 创建购物车页面组件

在components/创建Cart .vue组件文件

<template>
    <div class="cart">
      <Header/>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
    name: "Cart",
    data(){
      return{

      }
    },
    components:{Header,Footer}
}
</script>

<style scoped>

</style>


7.2 注册路由地址

routers/index.js代码:

import Cart from "@/components/Cart"

export default new Router({
  // 路由跳转模式,注意使用 history
  mode: "history",

  // 路由规则
  routes:[
    。。。
    ,{
      name:"Cart",
      path: "/cart",
      component: Cart,
    },
  ]
})

7.3 显示表格数据

<template>
    <div class="cart">
      <Header/>
      <div class="main">
        <div class="cart-title">
          <h3>我的购物车 <span> 共2门课程</span></h3>
          <el-table :data="courseData" style="width:100%">
            <el-table-column type="selection" label="" width="87"></el-table-column>
            <el-table-column prop="title" label="课程" width="540"></el-table-column>
            <el-table-column prop="expire" label="有效期" width="216"></el-table-column>
            <el-table-column prop="price" label="单价" width="162"></el-table-column>
            <el-table-column label="操作" width="162"></el-table-column>
          </el-table>
        </div>
        <div calss="cart-info"></div>
      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
    name: "Cart",
    data(){
      return{
        courseData:[
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
          {title:"课程标题一",expire:"2016",price:"12.00"},
        ]
      }
    },
    components:{Header,Footer}
}
</script>

<style scoped>
.main{
  width: 1200px;
  margin: 0 auto;
  overflow: hidden; /* 解决body元素和标题之间的上下外边距的塌陷问题 */
}
.cart-title h3{
  font-size: 18px;
  color: #666;
  margin: 25px 0;
}
.cart-title h3 span{
  font-size: 12px;
  color: #d0d0d0;
  display: inline-block;
}
</style>

接下来, 我们需要在表格中输出其他的图片或者链接信息,在elementUI提供的表格组件中,我们可以使用template标签来完成.

            <el-table-column prop="title" label="课程" width="540">
              <template slot-scope="scope">
                <img src="../../static/course/1544059695.jpeg" alt="">
                <a href="">千台服务器管理系统开发实战</a>
              </template>
            </el-table-column>

7.4完善购物车中的数据展示

Cart.vue,代码:

<template>
    <div class="cart">
      <Header/>
      <div class="main">
        <div class="cart-title">
          <h3>我的购物车 <span> 共2门课程</span></h3>
        </div>
        <div class="cart-info">
          <el-table :data="courseData" style="width:100%">
            <el-table-column type="selection" label="" width="87"></el-table-column>
            <el-table-column label="课程" width="540">
              <template slot-scope="scope">
                <div class="course-box">
                  <img :src="scope.row.img" alt="">
                  {{scope.row.title}}
                </div>
              </template>
            </el-table-column>
            <el-table-column label="有效期" width="216">
              <template slot-scope="scope">
                <el-form ref="form" label-width="60px">
                  <el-form-item>
                    <el-select v-model="expire" placeholder="请选择有效期">
                      <el-option v-for="item in expire_list" :key="item.id" :label="item.title" :value="item.id"></el-option>
                    </el-select>
                  </el-form-item>
                </el-form>
              </template>
            </el-table-column>
            <el-table-column label="单价" width="162">
              <template slot-scope="scope">¥{{ scope.row.price }}</template>
            </el-table-column>
            <el-table-column label="操作" width="162">
              <a href="">删除</a>
            </el-table-column>
          </el-table>
        </div>
        <div class="cart-bottom">
          <div class="select-all"><el-checkbox>全选</el-checkbox></div>
          <div class="delete-any"><img src="../../static/img/ico3.png" alt="">删除</div>
          <div class="cart-bottom-right">
            <span class="total">总计:¥<span>0.0</span></span>
            <span class="go-pay">去结算</span>
          </div>
        </div>
      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
    name: "Cart",
    data(){
      return{
        expire:3,
        expire_list:[
            {title:"一个月有效",id:1},
            {title:"两个月有效",id:2},
            {title:"三个月有效",id:3},
            {title:"永久有效",id:4},
        ],
        courseData:[
          {img:"../../static/course/1544059695.jpeg",title:"课程标题一",expire:"2016",price:"12.00"},
          {img:"../../static/course/1544059695.jpeg",title:"课程标题一",expire:"2016",price:"12.00"},
        ]
      }
    },
    components:{Header,Footer}
}
</script>

<style scoped>
.main{
  width: 1200px;
  margin: 0 auto;
  overflow: hidden; /* 解决body元素和标题之间的上下外边距的塌陷问题 */
}
.cart-title h3{
  font-size: 18px;
  color: #666;
  margin: 25px 0;
}
.cart-title h3 span{
  font-size: 12px;
  color: #d0d0d0;
  display: inline-block;
}
.course-box img{
    max-width: 175px;
    max-height: 115px;
    margin-right: 35px;
    vertical-align: middle;
}
.cart-bottom{
  overflow: hidden;
  height: 80px;
  background: #F7F7F7;
  margin-bottom: 300px;
  margin-top: 50px;
}
.select-all{
  float: left;
  margin-right: 58px;
  line-height: 80px;
}
.delete-any{
  cursor: pointer;
  float: left;
  line-height: 80px;
}
.delete-any img{
  width:18px;
  height: 18px;
  vertical-align: middle;
  padding-right: 15px;
}
.cart-bottom-right{
  float: right;
  text-align: right; /* 文本右对齐 */
}
.total{
  margin-right: 62px;
  font-size: 18px;
  color: #666;
}
.go-pay{
  outline: none;
  background: #ffc210;
  display: inline-block;
  padding: 27px 50px;
  font-size: 18px;
  cursor: pointer;
  color: #fff;
}
</style>


App.vue,增加修改css样式的代码:

  .el-checkbox__inner{
    width:16px;
    height: 16px;
    border: 1px solid #999;
  }
  .el-checkbox__inner:after{
    width: 6px;
    height: 8px;
  }
  .el-form-item__content{
    margin-left:0px!important;
    width: 120px;
  }

8.课程详情页

创建课程详情页的组件Detai.vue,基本代码结构:

<template>
    <div class="detail">
      <Header/>
      <div class="main">

      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
    name: "Detail",
    data(){
      return {}
    },
    components:{
      Header,
      Footer,
    }
}
</script>

<style scoped>

</style>

在router/index.js中增加路由

import Detail from "@/components/Detail"

  // 路由规则
  routes:[
    ,{
      name:"Detail",
      path: "/detail",
      component: Detail,
    },
  ]
})


在课程列表页中的li里面新增一个router-link 跳转链接。

<template>
  <div class="course">
    <Header/>
    <div class="main">
      <!-- 筛选功能 -->
      <div class="top">
        <ul class="condition condition1">
          <li class="cate-condition">课程分类:</li>
          <li class="item current">全部</li>
          <li class="item">Python</li>
          <li class="item">Linux运维</li>
          <li class="item">Python进阶</li>
          <li class="item">开发工具</li>
          <li class="item">Go语言</li>
          <li class="item">机器学习</li>
          <li class="item">技术生涯</li>
        </ul>
        <ul class="condition condition2">
          <li class="cate-condition">筛&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;选:</li>
          <li class="item current">默认</li>
          <li class="item">人气</li>
          <li class="item price">价格</li>
          <li class="course-length">共21个课程</li>
        </ul>
      </div>
      <!-- 课程列表 --->
      <div class="list">
        <ul>
          <li class="course-item">
            <router-link to="/detail" class="course-link">
              <div class="course-cover">...
              <div class="course-info">...               
            </router-link>
          </li>
          ...../// 省略代码
</template>


<style scoped>
.course-link{
  overflow: hidden;
}
</style>

8.1课程基本信息展示

Detail.vue,代码:

<template>
    <div class="detail">
      <Header/>
      <div class="main">
        <div class="course-info">
          <div class="wrap-left"></div>
          <div class="wrap-right">
            <h3 class="name">Linux系统基础5周入门精讲</h3>
            <p class="data">23475人在学&nbsp;&nbsp;&nbsp;&nbsp;课程总时长:148课时/180小时&nbsp;&nbsp;&nbsp;&nbsp;难度:初级</p>
            <div class="sale-time">
              <p class="sale-type">限时免费</p>
              <p class="expire">距离结束:仅剩 01天 04小时 33分 <span class="second">08</span> 秒</p>
            </div>
            <p class="course-price">
              <span>活动价</span>
              <span class="discount">¥0.00</span>
              <span class="original">¥29.00</span>
            </p>
            <div class="buy">
              <div class="buy-btn">
                <button class="buy-now">立即购买</button>
                <button class="free">免费试学</button>
              </div>
              <div class="add-cart"><img src="@/assets/cart-yellow.svg" alt="">加入购物车</div>
            </div>
          </div>
        </div>
      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"
export default {
    name: "Detail",
    data(){
      return {}
    },
    components:{
      Header,
      Footer,
    }
}
</script>

<style scoped>
.main{
  background: #fff;
  padding-top: 30px;
}
.course-info{
  width: 1200px;
  margin: 0 auto;
  overflow: hidden;
}
.wrap-left{
  float: left;
  width: 690px;
  height: 388px;
  background-color: #000;
}
.wrap-right{
  float: left;
  position: relative;
  height: 388px;
}
.name{
  font-size: 20px;
  color: #333;
  padding: 10px 23px;
  letter-spacing: .45px;
}
.data{
  padding-left: 23px;
  padding-right: 23px;
  padding-bottom: 16px;
  font-size: 14px;
  color: #9b9b9b;
}
.sale-time{
  width: 464px;
  background: #fa6240;
  font-size: 14px;
  color: #4a4a4a;
  padding: 10px 23px;
  overflow: hidden;
}
.sale-type {
  font-size: 16px;
  color: #fff;
  letter-spacing: .36px;
  float: left;
}
.sale-time .expire{
  font-size: 14px;
  color: #fff;
  float: right;
}
.sale-time .expire .second{
  width: 24px;
  display: inline-block;
  background: #fafafa;
  color: #5e5e5e;
  padding: 6px 0;
  text-align: center;
}
.course-price{
  background: #fff;
  font-size: 14px;
  color: #4a4a4a;
  padding: 5px 23px;
}
.discount{
  font-size: 26px;
  color: #fa6240;
  margin-left: 10px;
  display: inline-block;
  margin-bottom: -5px;
}
.original{
  font-size: 14px;
  color: #9b9b9b;
  margin-left: 10px;
  text-decoration: line-through;
}
.buy{
  width: 464px;
  padding: 0px 23px;
  position: absolute;
  left: 0;
  bottom: 20px;
  overflow: hidden;
}
.buy .buy-btn{
  float: left;
}
.buy .buy-now{
  width: 125px;
  height: 40px;
  border: 0;
  background: #ffc210;
  border-radius: 4px;
  color: #fff;
  cursor: pointer;
  margin-right: 15px;
  outline: none;
}
.buy .free{
  width: 125px;
  height: 40px;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 15px;
  background: #fff;
  color: #ffc210;
  border: 1px solid #ffc210;
}
.add-cart{
  float: right;
  font-size: 14px;
  color: #ffc210;
  text-align: center;
  cursor: pointer;
  margin-top: 10px;
}
.add-cart img{
  width: 20px;
  height: 18px;
  margin-right: 7px;
  vertical-align: middle;
}
</style>

效果:

1556533780731

8.2使用vue-video播放器

线上的路飞学城使用了AliPlayer阿里播放器。

我们本次项目使用vue-video播放器,是专门提供给vue项目使用。使用只需要完成四个步骤:

  1. 安装依赖
npm install vue-video-player --save

  1. 在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 App from './App'
import router from "./routers/index"

// ElementUI plugin
import ElementUI from "element-ui"
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI);

// vue-video plugin
import 'video.js/dist/video-js.css';
import "vue-video-player/src/custom-theme.css";
import VideoPlayer from "vue-video-player";
Vue.use(VideoPlayer);

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
});

  1. 在课程详情页中的script标签配置播放器的参数,以下代码:
import {videoPlayer} from 'vue-video-player';

export default {
  data () {
    return {
      playerOptions: {
        playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
        autoplay: false, //如果true,则自动播放
        muted: false, // 默认情况下将会消除任何音频。
        loop: false, // 循环播放
        preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
        language: 'zh-CN',
        aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
        sources: [{
          type: "video/mp4",
          src: "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4" //你的视频地址(必填)
        }],
        poster: "../static/courses/675076.jpeg", //视频封面图
        width: document.documentElement.clientWidth,
        notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
      }
    }
  },
  components: {
    videoPlayer
  },
  methods: {
    onPlayerPlay(player) {
      alert("play");
    },
    onPlayerPause(player){
      alert("pause");
    },
    player() {
      return this.$refs.videoPlayer.player
    }
  }
}

在html模板中调用video-player标签显示播放器

          <div class="warp-left" style="width: 690px;height: 388px;background-color: #000;">
            <video-player class="video-player vjs-custom-skin"
                 ref="videoPlayer"
                 :playsinline="true"
                 :options="playerOptions"
                 @play="onPlayerPlay($event)"
                 @pause="onPlayerPause($event)"
            >
            </video-player>
          </div>

效果:

1556538257873

集成了编辑器以后的课程详情页组件代码

<template>
    <div class="detail">
      <Header/>
      <div class="main">
        <div class="course-info">
          <div class="wrap-left">
            <video-player class="video-player vjs-custom-skin"
               ref="videoPlayer"
               :playsinline="true"
               :options="playerOptions"
               @play="onPlayerPlay($event)"
               @pause="onPlayerPause($event)"
            >
            </video-player>
          </div>
          <div class="wrap-right">
            <h3 class="name">Linux系统基础5周入门精讲</h3>
            <p class="data">23475人在学&nbsp;&nbsp;&nbsp;&nbsp;课程总时长:148课时/180小时&nbsp;&nbsp;&nbsp;&nbsp;难度:初级</p>
            <div class="sale-time">
              <p class="sale-type">限时免费</p>
              <p class="expire">距离结束:仅剩 01天 04小时 33分 <span class="second">08</span> 秒</p>
            </div>
            <p class="course-price">
              <span>活动价</span>
              <span class="discount">¥0.00</span>
              <span class="original">¥29.00</span>
            </p>
            <div class="buy">
              <div class="buy-btn">
                <button class="buy-now">立即购买</button>
                <button class="free">免费试学</button>
              </div>
              <div class="add-cart"><img src="@/assets/cart-yellow.svg" alt="">加入购物车</div>
            </div>
          </div>
        </div>
      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"

import {videoPlayer} from 'vue-video-player';

export default {
    name: "Detail",
    data(){
      return {
        playerOptions: {
          playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
          autoplay: false, //如果true,则自动播放
          muted: false, // 默认情况下将会消除任何音频。
          loop: false, // 循环播放
          preload: 'auto',  // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
          language: 'zh-CN',
          aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
          fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
          sources: [{ // 播放资源和资源格式
            type: "video/mp4",
            src: "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4" //你的视频地址(必填)
          }],
          poster: "../static/courses/675076.jpeg", //视频封面图
          width: document.documentElement.clientWidth, // 默认视频全屏时的最大宽度
          notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
        }
      }
    },
    methods: {
      // 视频播放事件
      onPlayerPlay(player) {
        alert("play");
      },
      // 视频暂停播放事件
      onPlayerPause(player){
        alert("pause");
      },
      // 视频插件初始化
      player() {
        return this.$refs.videoPlayer.player;
      }
    },
    components:{
      Header,
      Footer,
      videoPlayer,
    }
}
</script>

<style scoped>
.main{
  background: #fff;
  padding-top: 30px;
}
.course-info{
  width: 1200px;
  margin: 0 auto;
  overflow: hidden;
}
.wrap-left{
  float: left;
  width: 690px;
  height: 388px;
  background-color: #000;
}
.wrap-right{
  float: left;
  position: relative;
  height: 388px;
}
.name{
  font-size: 20px;
  color: #333;
  padding: 10px 23px;
  letter-spacing: .45px;
}
.data{
  padding-left: 23px;
  padding-right: 23px;
  padding-bottom: 16px;
  font-size: 14px;
  color: #9b9b9b;
}
.sale-time{
  width: 464px;
  background: #fa6240;
  font-size: 14px;
  color: #4a4a4a;
  padding: 10px 23px;
  overflow: hidden;
}
.sale-type {
  font-size: 16px;
  color: #fff;
  letter-spacing: .36px;
  float: left;
}
.sale-time .expire{
  font-size: 14px;
  color: #fff;
  float: right;
}
.sale-time .expire .second{
  width: 24px;
  display: inline-block;
  background: #fafafa;
  color: #5e5e5e;
  padding: 6px 0;
  text-align: center;
}
.course-price{
  background: #fff;
  font-size: 14px;
  color: #4a4a4a;
  padding: 5px 23px;
}
.discount{
  font-size: 26px;
  color: #fa6240;
  margin-left: 10px;
  display: inline-block;
  margin-bottom: -5px;
}
.original{
  font-size: 14px;
  color: #9b9b9b;
  margin-left: 10px;
  text-decoration: line-through;
}
.buy{
  width: 464px;
  padding: 0px 23px;
  position: absolute;
  left: 0;
  bottom: 20px;
  overflow: hidden;
}
.buy .buy-btn{
  float: left;
}
.buy .buy-now{
  width: 125px;
  height: 40px;
  border: 0;
  background: #ffc210;
  border-radius: 4px;
  color: #fff;
  cursor: pointer;
  margin-right: 15px;
  outline: none;
}
.buy .free{
  width: 125px;
  height: 40px;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 15px;
  background: #fff;
  color: #ffc210;
  border: 1px solid #ffc210;
}
.add-cart{
  float: right;
  font-size: 14px;
  color: #ffc210;
  text-align: center;
  cursor: pointer;
  margin-top: 10px;
}
.add-cart img{
  width: 20px;
  height: 18px;
  margin-right: 7px;
  vertical-align: middle;
}
</style>

8.3完成课程的选项卡内容部分以及讲师信息

<template>
    <div class="detail">
      <Header/>
      <div class="main">
        <div class="course-info">
          <div class="wrap-left">
            <video-player class="video-player vjs-custom-skin"
               ref="videoPlayer"
               :playsinline="true"
               :options="playerOptions"
               @play="onPlayerPlay($event)"
               @pause="onPlayerPause($event)"
            >
            </video-player>
          </div>
          <div class="wrap-right">
            <h3 class="course-name">Linux系统基础5周入门精讲</h3>
            <p class="data">23475人在学&nbsp;&nbsp;&nbsp;&nbsp;课程总时长:148课时/180小时&nbsp;&nbsp;&nbsp;&nbsp;难度:初级</p>
            <div class="sale-time">
              <p class="sale-type">限时免费</p>
              <p class="expire">距离结束:仅剩 01天 04小时 33分 <span class="second">08</span> 秒</p>
            </div>
            <p class="course-price">
              <span>活动价</span>
              <span class="discount">¥0.00</span>
              <span class="original">¥29.00</span>
            </p>
            <div class="buy">
              <div class="buy-btn">
                <button class="buy-now">立即购买</button>
                <button class="free">免费试学</button>
              </div>
              <div class="add-cart"><img src="@/assets/cart-yellow.svg" alt="">加入购物车</div>
            </div>
          </div>
        </div>
        <div class="course-tab">
          <ul class="tab-list">
            <li :class="tabIndex==1?'active':''" @click="tabIndex=1">详情介绍</li>
            <li :class="tabIndex==2?'active':''" @click="tabIndex=2">课程章节 <span :class="tabIndex!=2?'free':''">(试学)</span></li>
            <li :class="tabIndex==3?'active':''" @click="tabIndex=3">用户评论 (42)</li>
            <li :class="tabIndex==4?'active':''" @click="tabIndex=4">常见问题</li>
          </ul>
        </div>
        <div class="course-content">
          <div class="course-tab-list">
            <div class="tab-item" v-if="tabIndex==1">
              <p><img alt="" src="https://hcdn1.luffycity.com/static/frontend/course/12/Linux01_1547102274.4025493.jpeg" width="840"></p>
              <p><img alt="" src="https://hcdn1.luffycity.com/static/frontend/course/12/Linux02_1547102275.9939013.jpeg" width="840"></p>
              <p><img alt="" src="https://hcdn1.luffycity.com/static/frontend/course/12/Linux03_1547102275.730511.jpeg" width="840"></p>
            </div>
            <div class="tab-item" v-if="tabIndex==2">
              <div class="tab-item-title">
                <p class="chapter">课程章节</p>
                <p class="chapter-length">共11章 147个课时</p>
              </div>
              <div class="chapter-item">
                <p class="chapter-title"><img src="@/assets/1.svg" alt="">第1章·Linux硬件基础</p>
                <ul class="lesson-list">
                  <li class="lesson-item">
                    <p class="name"><span class="index">1-1</span> 课程介绍-学习流程<span class="free">免费</span></p>
                    <p class="time">07:30 <img src="@/assets/chapter-player.svg"></p>
                    <button class="try">立即试学</button>
                  </li>
                  <li class="lesson-item">
                    <p class="name"><span class="index">1-2</span> 服务器硬件-详解<span class="free">免费</span></p>
                    <p class="time">07:30 <img src="@/assets/chapter-player.svg"></p>
                    <button class="try">立即试学</button>
                  </li>
                </ul>
              </div>
              <div class="chapter-item">
                <p class="chapter-title"><img src="@/assets/1.svg" alt="">第2章·Linux发展过程</p>
                <ul class="lesson-list">
                  <li class="lesson-item">
                    <p class="name"><span class="index">2-1</span> 操作系统组成-Linux发展过程</p>
                    <p class="time">07:30 <img src="@/assets/chapter-player.svg"></p>
                    <button class="try">立即购买</button>
                  </li>
                  <li class="lesson-item">
                    <p class="name"><span class="index">2-2</span> 自由软件-GNU-GPL核心讲解</p>
                    <p class="time">07:30 <img src="@/assets/chapter-player.svg"></p>
                    <button class="try">立即购买</button>
                  </li>
                </ul>
              </div>
            </div>
            <div class="tab-item" v-if="tabIndex==3">
              用户评论
            </div>
            <div class="tab-item" v-if="tabIndex==4">
              常见问题
            </div>
          </div>
          <div class="course-side">
             <div class="teacher-info">
               <h4 class="side-title"><span>授课老师</span></h4>
               <div class="teacher-content">
                 <div class="cont1">
                   <img src="//hcdn1.luffycity.com/static/frontend/activity/头像@3x_1509542508.019424.png">
                   <div class="name">
                     <p class="teacher-name">李泳谊</p>
                     <p class="teacher-title">老男孩LInux学科带头人</p>
                   </div>
                 </div>
                 <p class="narrative" >Linux运维技术专家,老男孩Linux金牌讲师,讲课风趣幽默、深入浅出、声音洪亮到爆炸</p>
               </div>
             </div>
          </div>
        </div>
      </div>
      <Footer/>
    </div>
</template>

<script>
import Header from "./common/Header"
import Footer from "./common/Footer"

import {videoPlayer} from 'vue-video-player';

export default {
    name: "Detail",
    data(){
      return {
        tabIndex:2, // 当前选项卡显示的下标
        playerOptions: {
          playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
          autoplay: false, //如果true,则自动播放
          muted: false, // 默认情况下将会消除任何音频。
          loop: false, // 循环播放
          preload: 'auto',  // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
          language: 'zh-CN',
          aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
          fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
          sources: [{ // 播放资源和资源格式
            type: "video/mp4",
            src: "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4" //你的视频地址(必填)
          }],
          poster: "../static/courses/675076.jpeg", //视频封面图
          width: document.documentElement.clientWidth, // 默认视频全屏时的最大宽度
          notSupportedMessage: '此视频暂无法播放,请稍后再试', //允许覆盖Video.js无法播放媒体源时显示的默认信息。
        }
      }
    },
    methods: {
      // 视频播放事件
      onPlayerPlay(player) {
        alert("play");
      },
      // 视频暂停播放事件
      onPlayerPause(player){
        alert("pause");
      },
      // 视频插件初始化
      player() {
        return this.$refs.videoPlayer.player;
      }
    },
    components:{
      Header,
      Footer,
      videoPlayer,
    }
}
</script>

<style scoped>
.main{
  background: #fff;
  padding-top: 30px;
}
.course-info{
  width: 1200px;
  margin: 0 auto;
  overflow: hidden;
}
.wrap-left{
  float: left;
  width: 690px;
  height: 388px;
  background-color: #000;
}
.wrap-right{
  float: left;
  position: relative;
  height: 388px;
}
.course-name{
  font-size: 20px;
  color: #333;
  padding: 10px 23px;
  letter-spacing: .45px;
}
.data{
  padding-left: 23px;
  padding-right: 23px;
  padding-bottom: 16px;
  font-size: 14px;
  color: #9b9b9b;
}
.sale-time{
  width: 464px;
  background: #fa6240;
  font-size: 14px;
  color: #4a4a4a;
  padding: 10px 23px;
  overflow: hidden;
}
.sale-type {
  font-size: 16px;
  color: #fff;
  letter-spacing: .36px;
  float: left;
}
.sale-time .expire{
  font-size: 14px;
  color: #fff;
  float: right;
}
.sale-time .expire .second{
  width: 24px;
  display: inline-block;
  background: #fafafa;
  color: #5e5e5e;
  padding: 6px 0;
  text-align: center;
}
.course-price{
  background: #fff;
  font-size: 14px;
  color: #4a4a4a;
  padding: 5px 23px;
}
.discount{
  font-size: 26px;
  color: #fa6240;
  margin-left: 10px;
  display: inline-block;
  margin-bottom: -5px;
}
.original{
  font-size: 14px;
  color: #9b9b9b;
  margin-left: 10px;
  text-decoration: line-through;
}
.buy{
  width: 464px;
  padding: 0px 23px;
  position: absolute;
  left: 0;
  bottom: 20px;
  overflow: hidden;
}
.buy .buy-btn{
  float: left;
}
.buy .buy-now{
  width: 125px;
  height: 40px;
  border: 0;
  background: #ffc210;
  border-radius: 4px;
  color: #fff;
  cursor: pointer;
  margin-right: 15px;
  outline: none;
}
.buy .free{
  width: 125px;
  height: 40px;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 15px;
  background: #fff;
  color: #ffc210;
  border: 1px solid #ffc210;
}
.add-cart{
  float: right;
  font-size: 14px;
  color: #ffc210;
  text-align: center;
  cursor: pointer;
  margin-top: 10px;
}
.add-cart img{
  width: 20px;
  height: 18px;
  margin-right: 7px;
  vertical-align: middle;
}

.course-tab{
    width: 100%;
    background: #fff;
    margin-bottom: 30px;
    box-shadow: 0 2px 4px 0 #f0f0f0;

}
.course-tab .tab-list{
    width: 1200px;
    margin: auto;
    color: #4a4a4a;
    overflow: hidden;
}
.tab-list li{
    float: left;
    margin-right: 15px;
    padding: 26px 20px 16px;
    font-size: 17px;
    cursor: pointer;
}
.tab-list .active{
    color: #ffc210;
    border-bottom: 2px solid #ffc210;
}
.tab-list .free{
    color: #fb7c55;
}
.course-content{
    width: 1200px;
    margin: 0 auto;
    background: #FAFAFA;
    overflow: hidden;
    padding-bottom: 40px;
}
.course-tab-list{
    width: 880px;
    height: auto;
    padding: 20px;
    background: #fff;
    float: left;
    box-sizing: border-box;
    overflow: hidden;
    position: relative;
    box-shadow: 0 2px 4px 0 #f0f0f0;
}
.tab-item{
    width: 880px;
    background: #fff;
    padding-bottom: 20px;
    box-shadow: 0 2px 4px 0 #f0f0f0;
}
.tab-item-title{
    justify-content: space-between;
    padding: 25px 20px 11px;
    border-radius: 4px;
    margin-bottom: 20px;
    border-bottom: 1px solid #333;
    border-bottom-color: rgba(51,51,51,.05);
    overflow: hidden;
}
.chapter{
    font-size: 17px;
    color: #4a4a4a;
    float: left;
}
.chapter-length{
    float: right;
    font-size: 14px;
    color: #9b9b9b;
    letter-spacing: .19px;
}
.chapter-title{
    font-size: 16px;
    color: #4a4a4a;
    letter-spacing: .26px;
    padding: 12px;
    background: #eee;
    border-radius: 2px;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: center;
    align-items: center;
}
.chapter-title img{
    width: 18px;
    height: 18px;
    margin-right: 7px;
    vertical-align: middle;
}
.lesson-list{
    padding:0 20px;
}
.lesson-list .lesson-item{
    padding: 15px 20px 15px 36px;
    cursor: pointer;
    justify-content: space-between;
    position: relative;
    overflow: hidden;
}
.lesson-item .name{
    font-size: 14px;
    color: #666;
    float: left;
}
.lesson-item .index{
    margin-right: 5px;
}
.lesson-item .free{
    font-size: 12px;
    color: #fff;
    letter-spacing: .19px;
    background: #ffc210;
    border-radius: 100px;
    padding: 1px 9px;
    margin-left: 10px;
}
.lesson-item .time{
    font-size: 14px;
    color: #666;
    letter-spacing: .23px;
    opacity: 1;
    transition: all .15s ease-in-out;
    float: right;
}
.lesson-item .time img{
    width: 18px;
    height: 18px;
    margin-left: 15px;
    vertical-align: text-bottom;
}
.lesson-item .try{
    width: 86px;
    height: 28px;
    background: #ffc210;
    border-radius: 4px;
    font-size: 14px;
    color: #fff;
    position: absolute;
    right: 20px;
    top: 10px;
    opacity: 0;
    transition: all .2s ease-in-out;
    cursor: pointer;
    outline: none;
    border: none;
}
.lesson-item:hover{
    background: #fcf7ef;
    box-shadow: 0 0 0 0 #f3f3f3;
}
.lesson-item:hover .name{
    color: #333;
}
.lesson-item:hover .try{
    opacity: 1;
}

.course-side{
    width: 300px;
    height: auto;
    margin-left: 20px;
    float: right;
}
.teacher-info{
    background: #fff;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px 0 #f0f0f0;
}
.side-title{
    font-weight: normal;
    font-size: 17px;
    color: #4a4a4a;
    padding: 18px 14px;
    border-bottom: 1px solid #333;
    border-bottom-color: rgba(51,51,51,.05);
}
.side-title span{
    display: inline-block;
    border-left: 2px solid #ffc210;
    padding-left: 12px;
}

.teacher-content{
    padding: 30px 20px;
    box-sizing: border-box;
}

.teacher-content .cont1{
    margin-bottom: 12px;
    overflow: hidden;
}

.teacher-content .cont1 img{
    width: 54px;
    height: 54px;
    margin-right: 12px;
    float: left;
}
.teacher-content .cont1 .name{
    float: right;
}
.teacher-content .cont1 .teacher-name{
    width: 188px;
    font-size: 16px;
    color: #4a4a4a;
    padding-bottom: 4px;
}
.teacher-content .cont1 .teacher-title{
    width: 188px;
    font-size: 13px;
    color: #9b9b9b;
    white-space: nowrap;
}
.teacher-content .narrative{
    font-size: 14px;
    color: #666;
    line-height: 24px;
}
</style>

效果:

1556538277772

posted @ 2019-08-05 08:10  panky  阅读(561)  评论(0编辑  收藏  举报