• 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{
         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{
         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{
         15px;
        height: auto;
        margin-left: 6px;
      }
      .cart-ico span{
        margin-left: 12px;
      }
      .member img{
         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- 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{
       100%;
      height: 128px;
      background: #25292e;
    }
    .footer .el-container{
       1200px;
      margin: auto;
    }
    .footer .el-row {
      align-items: center;
      padding: 0 200px;
      padding-bottom: 15px;
       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{
       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{
         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: "";
         0;
        border: 5px solid transparent;
        border-top-color: #ffc210;
        position: absolute;
        right: 0;
        bottom: 2.5px;
      }
      .condition .price::after{
      content: "";
         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{
         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: "";
         0;
        border: 5px solid transparent;
        border-top-color: #ffc210;
        position: absolute;
        right: 0;
        bottom: 2.5px;
      }
      .condition .price::after{
      content: "";
         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{
         423px;
        height: 210px;
        margin-right: 30px;
        float: left;
      }
      .course-info{
         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{
         49%;
        margin-bottom: 15px;
        cursor: pointer;
        float: left;
        margin-right: 1%;
      }
      .lesson-list li .player{
         16px;
        height: 16px;
        vertical-align: text-bottom;
      }
      .lesson-list li .lesson-title{
        display: inline-block;
        max- 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{
         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{
         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{
         100%;
      }
    
      .header .el-menu li .el-submenu__title{
        height: 26px!important;
        line-height: 26px!important;
      }
      .el-menu--popup{
        min- 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;
         100%;
        box-shadow: 0 0.5px 0.5px 0 #c9c9c9;
      }
      .header .el-container{
         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{
         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{
         15px;
        height: auto;
        margin-left: 6px;
      }
      .cart-ico span{
        margin-left: 12px;
      }
      .cart-ico a{
        text-decoration: none;
      }
      .member img{
         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{
         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{
         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{
         15px;
        height: auto;
        margin-left: 6px;
      }
      .cart-ico span{
        margin-left: 12px;
      }
      .member img{
         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="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{
       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="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{
       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- 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{
      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{
        16px;
        height: 16px;
        border: 1px solid #999;
      }
      .el-checkbox__inner:after{
         6px;
        height: 8px;
      }
      .el-form-item__content{
        margin-left:0px!important;
         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{
       1200px;
      margin: 0 auto;
      overflow: hidden;
    }
    .wrap-left{
      float: left;
       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{
       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{
       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{
       464px;
      padding: 0px 23px;
      position: absolute;
      left: 0;
      bottom: 20px;
      overflow: hidden;
    }
    .buy .buy-btn{
      float: left;
    }
    .buy .buy-now{
       125px;
      height: 40px;
      border: 0;
      background: #ffc210;
      border-radius: 4px;
      color: #fff;
      cursor: pointer;
      margin-right: 15px;
      outline: none;
    }
    .buy .free{
       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{
       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", //视频封面图
             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=" 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", //视频封面图
               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{
       1200px;
      margin: 0 auto;
      overflow: hidden;
    }
    .wrap-left{
      float: left;
       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{
       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{
       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{
       464px;
      padding: 0px 23px;
      position: absolute;
      left: 0;
      bottom: 20px;
      overflow: hidden;
    }
    .buy .buy-btn{
      float: left;
    }
    .buy .buy-now{
       125px;
      height: 40px;
      border: 0;
      background: #ffc210;
      border-radius: 4px;
      color: #fff;
      cursor: pointer;
      margin-right: 15px;
      outline: none;
    }
    .buy .free{
       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{
       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", //视频封面图
               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{
       1200px;
      margin: 0 auto;
      overflow: hidden;
    }
    .wrap-left{
      float: left;
       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{
       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{
       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{
       464px;
      padding: 0px 23px;
      position: absolute;
      left: 0;
      bottom: 20px;
      overflow: hidden;
    }
    .buy .buy-btn{
      float: left;
    }
    .buy .buy-now{
       125px;
      height: 40px;
      border: 0;
      background: #ffc210;
      border-radius: 4px;
      color: #fff;
      cursor: pointer;
      margin-right: 15px;
      outline: none;
    }
    .buy .free{
       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{
       20px;
      height: 18px;
      margin-right: 7px;
      vertical-align: middle;
    }
    
    .course-tab{
         100%;
        background: #fff;
        margin-bottom: 30px;
        box-shadow: 0 2px 4px 0 #f0f0f0;
    
    }
    .course-tab .tab-list{
         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{
         1200px;
        margin: 0 auto;
        background: #FAFAFA;
        overflow: hidden;
        padding-bottom: 40px;
    }
    .course-tab-list{
         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{
         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{
         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{
         18px;
        height: 18px;
        margin-left: 15px;
        vertical-align: text-bottom;
    }
    .lesson-item .try{
         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{
         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{
         54px;
        height: 54px;
        margin-right: 12px;
        float: left;
    }
    .teacher-content .cont1 .name{
        float: right;
    }
    .teacher-content .cont1 .teacher-name{
         188px;
        font-size: 16px;
        color: #4a4a4a;
        padding-bottom: 4px;
    }
    .teacher-content .cont1 .teacher-title{
         188px;
        font-size: 13px;
        color: #9b9b9b;
        white-space: nowrap;
    }
    .teacher-content .narrative{
        font-size: 14px;
        color: #666;
        line-height: 24px;
    }
    </style>
    
    

    效果:

    1556538277772

  • 相关阅读:
    OpenLiveWriter博客工具
    mysql主从复制原理分析
    linux mysql主从复制配置
    linux mysql数据库安装
    linux 下安装maven私服
    eclipse新建maven项目和聚合项目
    入门Kubernetes -基础概念
    Java中5种List的去重方法及它们的效率对比,你用对了吗?
    谈一谈程序员的职业发展路线
    虚拟机中如何Linux系统如何访问PC硬盘中的文件(如何将windows下的文件夹挂载到linux虚拟机下)
  • 原文地址:https://www.cnblogs.com/pankypan/p/11300903.html
Copyright © 2020-2023  润新知