image-20200301185713657

WechatIMG1

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第一章 新版SSM-Springboot2.X-Spring5-Mybatis3专题课程介绍

第1集 新版Springboot2.X-Spring5-Mybatis3专题课程介绍

简介:讲解新版SSM专题课程介绍,课程适合人员和学后水平

 

u=1704237808,853679782&fm=15&gp=0

 

 

 

 

第2集 新版SSM+小滴课堂移动端系统实战+云服务器部署大纲速览

简介:新版SpringBoot-Spring-Mybatis 课程大纲你知道多少

 

 

 

 

 

第3集 必备基础-15分钟认识Spring5框架和基本概念

简介:15分钟认识Spring5框架和基本概念

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二章 微服务必备核心-快速入门SpringBoot2.X

第1集 你知道SpringBoot2.X和SpringCloud微服务的关系吗

简介:讲解微服务SpringCloud和SpringBoot的关系

 

 

 

第2集 新版SSM框架-SpringBoot2.X介绍和环境依赖

简介:讲解新版SSM框架之SpringBoot2.X介绍和环境依赖

 

 

第3集 玩转SpringBoot2.X项目创建工具Spring Initializr

简介:使用Spring Initializr创建SpringBoot2.X项目

 

 

 

第4集 企业工作或者学习新技术,遇到问题推荐的解决方式

简介:企业工作和学习IT技术,遇到问题常见的解决方式

 

 

第5集 新版SpringBoot2.X开发第一个JSON接口

简介:使用新版SpringBoot2.X开发第一个JSON接口

 

 

第6集 前后端分离测试必备工具PostMan接口工具使用

简介:模拟Http接口测试工具PostMan安装和讲解

 

第7集 新版SpringBoot2.X的常用注解你知多少

简介:讲解SpringBoot2.X常用的注解

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第三章 互联网公司中新版SpringBoot2.X开发规范解读

 

第1集 新版SpringBoot2.x目录文件结构讲解和静态资源访问

简介:讲解SpringBoot目录文件结构和官方推荐的目录规范、静态资源访问

第2集 新版SpringBoot2.x启动类位置常见形式

简介:讲解SpringBoot目录文件结构和官方推荐的目录规范

第3集 SpringBoot2.X启动方式讲解和部署

简介:讲解SpringBoot2.X启动方式

 

第4集 打包后的Jar里面的目录结构你知道多少

简介:讲解打包后的springboot里面的目录结构

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第四章 淘汰传统XX管理系统! 在线教育项目核心模块学SpringBoot2.X

 

第1集 小滴课堂在线教育项目原型需求分析

简介: 分析小滴课堂业务功能,通过开发项目掌握SpringBoot2.X

 

 

第2集 SpringBoot2.X在线教育项目架构搭建

简介: 创建对应的项目,划分好对应的包模块

 

 

第3集 SpringBoot2.X开发HTTP接口GET请求实战

简介:讲解springboot接口,http的get请求,各个注解使用

第4集 SpringBoot2.X统一接口返回协议-掌握开发规范

简介:讲解springboot自定义返回对象,统一协议

 

第5集 SpringBoot2.X开发HTTP接口POST请求实战

简介:讲解springboot接口,http的POST请求

 

 

第6集 实战RequestBody对象数组提交接口开发

简介:讲解JSON对象提交,批量插入接口开发

 

 

第7集 SpringBoot2.X里面定制JSON字段

简介:SpringBoot配置Jackson处理字段

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第五章 IDEA中SpringBoot2.X热部署Dev-tool和常见问题

 

第1集 什么是热部署,为啥要用这个呢

简介:介绍什么是热部署,使用的好处

 

 

第2集 SpringBoot2.X结合dev-tool 实现IDEA项目热部署

简介:讲解SpringBoot2.x使用dev-tool实现热部署

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第六章 最佳实践之SpringBoot.2.X里面的配置文件

 

第1集 带你看SpringBoot2.x常见配置文件形式

简介:SpringBoot2.x常见的配置文件形式 xml、yml、properties的区别和使用

 

 

第2集 新版SpringBoot注解配置文件映射属性和实体类实战

简介:讲解使用@value注解配置文件自动映射到属性和实体类

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第七章 项目实战中的Springboot2.X单元测试应用

 

第1集 公司里面软件开发测试流程你知道多少

简介:讲解公司里面软件开发测试

 

第2集 在线教育项目里面怎么用SpringBoot2.x的单元测试

简介:讲解项目里面怎么使用SpringBoot2.x的单元测试

 

 

第3集 案例实战单元测试调用Controller-Service层接口

简介:讲解Springboot单元测试Controller-Service层接口

 

 

第4集 MockMvc案例实战调用Controller层API接口

简介:讲解Springboot的MockMvc调用api层接口

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第八章 项目实战中的Springboot2.X全局异常处理

 

第1集 SpringBoot2.x在线教育项目中里面的全局异常处理

简介:讲解SpringBoot2.X全局异常处理

 

第2集 SpringBoot2.x自定义全局异常返回页面

简介:使用SpringBoot自定义异常和错误页面跳转实战

<dependency>
	   <groupId>org.springframework.boot</groupId>
	   <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error.html");
modelAndView.addObject("msg", e.getMessage());
return modelAndView;

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第九章 新版Servlet3.0和SpringBoot2.X过滤器-拦截器实战

第1集 SpringBoot2.X过滤器讲解

简介:SpringBoot2.X过滤器讲解

 

第2集 抛弃传统方式,使用新版Servlet3.0的注解开发自定义Filter

简介:使用Servlet3.0注解开发自定义的过滤器

 

第3集 前后端分离-自定义Filter 未登录json错误码提示开发

简介:使用Servlet3.0注解开发自定义的过滤器,返回未登录错误码

private void renderJson(HttpServletResponse response,String json){

        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");

        try(PrintWriter writer = response.getWriter()){
            writer.print(json);
        }catch (Exception e){
            e.printStackTrace();
        }

}

 

第4集 回归本质Servlet3.0的注解原生Servlet实战

简介:使用 Servlet3.0的注解自定义原生Servlet

@WebServlet(name = "userServlet", urlPatterns = "/api/v1/test/customs" )
class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        PrintWriter writer = resp.getWriter();
        writer.write("this is my custom servlet");
        writer.flush();
        writer.close();

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }

}

 

第5集 Servlet3.0+SpringBoot2.X 注解Listener常用监听器

简介:监听器介绍和Servlet3.0的注解自定义原生Listener监听器实战

@WebListener
public class RequestListener implements ServletRequestListener {

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("======contextDestroyed========");
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
            System.out.println("======contextInitialized========");

    }
}

 

第6集 新版SpringBoot2.X拦截器配置实战

简介: 讲解Spingboot2.x新版本配置拦截器在项目中的使用

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十章 新版SpringBoot2.X 整合模板引擎thymeleaf和Fk

 

第1集 新版SpringBoot2.x的starter和常见模板引擎讲解

简介:介绍常用的SpringBoot2.x模板引擎和官方推荐案例

 

 

第2集 SpringBoot2.X整合模板引擎freemarker实战

简介:SpringBoot2.x整合模板引擎freemarker实战

 

 

第3集 SpringBoot2.X整合模板引擎thymeleaf实战

讲解:SpringBoot2.x整合模板引擎thymeleaf实战

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十一章 玩转新版SpringBoot2.X整合定时任务和异步任务

第1集 SpringBoot2.X定时任务schedule讲解

简介:讲解什么是定时任务和常见定时任务区别

 

 

 

第2集 SpringBoot2.X多种定时任务配置实战

简介:SpringBoot常用定时任务表达式配置和在线生成器

 

第3集 玩转SpringBoot2.x异步任务EnableAsync实战

简介:讲解什么是异步任务,和使用SpringBoot2.x开发异步任务实战

 

第4集 玩转SpringBoot2.x异步任务Future实战

简介:使用SpringBoot2.x开发异步任务Future获取结果

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十二章 带你设计在线教育项目核心数据库表

 

第1集 在线教育项目核心数据库表设计-ER图

简介:设计在线教育的核心库表结构

image-20200409233830688

 

 

第2集 在线教育项目核心数据库表字段设计和测试数据准备

简介:设计在线教育的核心库表结构

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十三章 从Javaweb原生jdbc到快速掌握新版MyBatis3.X

 

第1集 回顾javaweb通过原生jdbc访问数据库

简介:回顾基础使用原生jdbc访问数据库

 

 

第2集 原生JDBC访问数据库的缺点和ORM框架介绍

简介:原生jdbc访问数据库缺点和ORM框架介绍

 

第3集 新版ORM框架Mybatis3.X基础知识

简介:快速掌握新版Mybaits3.X

 

image-20200411134415859

第4集 新版Mybatis3.X快速入门实战《上》

简介:快速掌握新版Mybaits3.X实战,编写 mybatis-confifg.xml和mapper.xml

 

第5集 新版Mybatis3.X快速入门实战《下》

简介:快速掌握新版Mybaits3.X实战,SqlSession代码实战

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十四章 案例实战MyBatis3.X玩转查询和新增操作

 

第1集 新版Mybatis开发必备调试之控制台打印Sql

简介:讲解Mybatis在控制台打印sql

 

第2集 Mybatis实战参数别名使用之查询视频列表

简介:讲解Mybatis查询视频列表和参数别名的使用

 

 

 

第3集 Mybatis 配置驼峰字段映射java对象和数据库字段

简介:讲解Mybatis配置驼峰字段到java类

第4集 Mybatis入参parameterType和取值类型讲解

简介:讲解Mybatis入参 parameterType和取值类型讲解

 

第5集 Mybatis实战插入语法之视频新增和自增主键

简介:讲解Mybatis插入语法的使用和如何获得自增主键

 

 

 

第6集 Mybatis实战foreach批量插入语法之视频批量插入

简介:讲解Mybatis foreach批量插入语法的使用

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十五章 案例实战MyBatis3.X玩转更新和删除

 

第1集 MyBatis3.X实战更新语法之视频更新操作

简介:讲解Mybatis视频更新操作

 

 

第2集 MyBatis3.X实战 更新语法之选择性更新标签使用

简介:讲解Mybatis 动态字段更新 if test 标签使用

 

第3集 MyBatis3.X实战之删除语法和转义字符使用

简介:讲解Mybatis删除语法操作

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十六章 新版MyBatis3.X玩转常见配置

 

第1集 MyBatis3.X 配置文件mybatis-config.xml常见属性

简介:讲解Mybatis的mybatis-config.xml常见配置

 

 

第2集 MyBatis3.X 查询typeAlias别名的使用

简介:讲解Mybatis的查询类别名typeAlias的使用

<!--<select id="selectById" parameterType="java.lang.Integer" resultType="net.xdclass.online_class.domain.Video">-->
    <select id="selectById" parameterType="java.lang.Integer" resultType="Video">
        select * from video where id = #{video_id,jdbcType=INTEGER}

    </select>

 

第3集 高性能sql之MyBatis3.X的Sql片段使用

简介:讲解Mybatis的sql片段的使用

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十七章 进阶MyBatis3.X复杂Sql查询

 

第1集 MyBatis3.X的resultMap 你知道多少

简介:讲解Mybatis的resultMap讲解

<resultMap id="VideoResultMap" type="Video">

        <!--
        id 指定查询列的唯一标示
        column 数据库字段的名称
        property pojo类的名称
        -->
        <id column="id" property="id" jdbcType="INTEGER" />

        <result column="video_tile" property="title"  jdbcType="VARCHAR" />
        <result column="summary" property="summary"  jdbcType="VARCHAR" />
        <result column="cover_img"  property="coverImg"  jdbcType="VARCHAR" />

</resultMap>
<select id="selectBaseFieldByIdWithResultMap" resultMap="VideoResultMap">
select id , title as video_tile, summary, cover_img from video where id = #{video_id}
</select>

第2集 ResultMap复杂对象一对一查询结果映射之association

简介:讲解Mybatis 复杂对象映射配置ResultMap的association

  <resultMap id="VideoOrderResultMap" type="VideoOrder">
        <id column="id" property="id"/>

        <result column="user_id" property="userId"/>
        <result column="out_trade_no" property="outTradeNo"/>
        <result column="create_time" property="createTime"/>
        <result column="state" property="state"/>
        <result column="total_fee" property="totalFee"/>
        <result column="video_id" property="videoId"/>
        <result column="video_title" property="videoTitle"/>
        <result column="video_img" property="videoImg"/>


        <!--
         association 配置属性一对一
         property 对应videoOrder里面的user属性名
         javaType 这个属性的类型
         -->
        <association property="user" javaType="User">
            <id property="id"  column="user_id"/>
            <result property="name" column="name"/>
            <result property="headImg" column="head_img"/>
            <result property="createTime" column="create_time"/>
            <result property="phone" column="phone"/>
        </association>

    </resultMap>

    <!--一对一管理查询订单, 订单内部包含用户属性-->
    <select id="queryVideoOrderList" resultMap="VideoOrderResultMap">

        select

         o.id id,
         o.user_id ,
         o.out_trade_no,
         o.create_time,
         o.state,
         o.total_fee,
         o.video_id,
         o.video_title,
         o.video_img,
         u.name,
         u.head_img,
         u.create_time,
         u.phone
         from video_order o left join user u on o.user_id = u.id

    </select>

 

 

第3集 ResultMap复杂对象一对多查询结果映射之collection

简介:讲解Mybatis 复杂对象一对多映射配置ResultMap的collection

<resultMap id="UserOrderResultMap" type="User">

        <id property="id"  column="id"/>
        <result property="name" column="name"/>
        <result property="headImg" column="head_img"/>
        <result property="createTime" column="create_time"/>
        <result property="phone" column="phone"/>

        <!--
        property 填写pojo类中集合类属性的名称
        ofType 集合里面的pojo对象
        -->
        <collection property="videoOrderList" ofType="VideoOrder">

            <!--配置主键,管理order的唯一标识-->
            <id column="order_id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="out_trade_no" property="outTradeNo"/>
            <result column="create_time" property="createTime"/>
            <result column="state" property="state"/>
            <result column="total_fee" property="totalFee"/>
            <result column="video_id" property="videoId"/>
            <result column="video_title" property="videoTitle"/>
            <result column="video_img" property="videoImg"/>
        </collection>
    </resultMap>

    <select id="queryUserOrder" resultMap="UserOrderResultMap">
        select
        u.id,
        u.name,
        u.head_img,
        u.create_time,
        u.phone,
        o.id order_id,
        o.out_trade_no,
        o.user_id,
        o.create_time,
        o.state,
        o.total_fee,
        o.video_id,
        o.video_title,
        o.video_img
        from user u left join video_order o on u.id = o.user_id

    </select>

第4集 Mybatis3.X ResultMap复杂对象查询总结

简介:总结ResultMap的复杂对象查询

<!-- column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
  <id column="表的主键字段,或查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
  <result column="表的一个字段" jdbcType="字段类型" property="映射到pojo对象的一个属性"/>

  <association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
    <id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
    <result  column="表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
  </association>

  <!-- 集合中的property 需要为oftype定义的pojo对象的属性-->
  <collection property="pojo的集合属性名称" ofType="集合中单个的pojo对象类型">
    <id column="集合中pojo对象对应在表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
    <result column="任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />  
  </collection>
</resultMap>

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十八章 面试章-MyBatis3.X高手系列-玩转多级缓存和懒加载

 

第1集 Mybatis3.X 一级缓存讲解和案例实战

简介:讲解Mybatis一级缓存介绍和验证

第2集 你知道Mybatis3.X 二级缓存怎么使用《上》

简介:讲解Mybatis二级缓存和配置实操

 

 

 

第3集 你知道Mybatis3.X 二级缓存怎么使用《下》

简介:讲解Mybatis二级缓存和配置实操

第4集 你知道Mybatis3.X 懒加载吗-看这个就懂了?

简介:讲解Mybatis3.x的懒加载

<!--全局参数设置-->
<settings>
    <!--延迟加载总开关-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--将aggressiveLazyLoading设置为false表示按需加载,默认为true-->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

 

<resultMap id="VideoOrderResultMapLazy" type="VideoOrder">
        <id column="id" property="id"/>

        <result column="user_id" property="userId"/>
        <result column="out_trade_no" property="outTradeNo"/>
        <result column="create_time" property="createTime"/>
        <result column="state" property="state"/>
        <result column="total_fee" property="totalFee"/>
        <result column="video_id" property="videoId"/>
        <result column="video_title" property="videoTitle"/>
        <result column="video_img" property="videoImg"/>

<!-- 
select: 指定延迟加载需要执行的statement id 
column: 和select查询关联的字段
-->
        <association property="user" javaType="User" column="user_id" select="findUserByUserId"/>


</resultMap>

    <!--一对一管理查询订单, 订单内部包含用户属性  懒加载-->
<select id="queryVideoOrderListLazy" resultMap="VideoOrderResultMapLazy">

        select
         o.id id,
         o.user_id ,
         o.out_trade_no,
         o.create_time,
         o.state,
         o.total_fee,
         o.video_id,
         o.video_title,
         o.video_img
         from video_order o

</select>


<select id="findUserByUserId" resultType="User">

       select  * from user where id=#{id}

</select>
// resultmap association关联查询(测试懒加载)
VideoOrderMapper videoOrderMapper = sqlSession.getMapper(VideoOrderMapper.class);
List<VideoOrder> videoOrderList = videoOrderMapper.queryVideoOrderListLazy();
System.out.println(videoOrderList.size());

//课程里面演示是6条订单记录,但是只查询3次用户信息,是因为部分用户信息走了一级缓存sqlsession
for(VideoOrder videoOrder : videoOrderList){

    System.out.println(videoOrder.getVideoTitle());
    System.out.println(videoOrder.getUser().getName());
}

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第十九章 MyBatis3.X高手系列之整合Mysql数据库事务

 

第1集 新版MyBatis3.x 的事务管理形式

简介:讲解Mybatis的事务管理形式

 

 

<environment id="development">
            <!-- mybatis使用jdbc事务管理方式 -->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/xdclass?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="xdclass.net"/>
            </dataSource>
</environment>

 

 

 

第2集 面试题-Mysql的Innodb和MyISAM引擎的区别

简介:讲解mysql常见的两种存储引擎的区别

 

第3集 新版MyBatis3.x 的事务控制 - 走读源码和案例

简介:讲解mybatis事务控制实战

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十章 新版SSM之Spring Framework5.X快速入门

第1集 快速认知-新版Spring Framework5.X

简介:讲解什么是spring框架,使用的好处

 

 

第2集 IDEA+Maven+Spring5.X项目创建

简介:使用 IDEA + Maven + Spring5创建项目

 

第3集 ApplicationContext.xml配置文件讲解和Helloworld例子解读

简介:讲解Spring5.x的applicationContext.xml配置文件和例子回顾

 

第4集 新版SpringFramework5.X核心之 IOC 容器讲解

简介:讲解spring的IOC设计思想

 

image-20200415190928518

 

 

第5集 新版SpringFramework5.X核心之 DI依赖注入讲解

简介:讲解spring的依赖注入讲解

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十一章 玩转Spring5.X bean 的作用域和注入

 

第1集 新版Spring5.x的bean的scope作用域讲解

简介:讲解spring的bean 属性scope作用域

 

第2集 实战Spring5.X常见的注入方式

简介:讲解spring的常见的注入方式

<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">

        <property name="id" value="9"/>
        <property name="title" value="Spring 5.X课程" />

</bean>
    <bean id="video" class="net.xdclass.sp.domain.Video" >

        <constructor-arg name="title" value="面试专题课程第一季"></constructor-arg>

    </bean>
  <bean id="video" class="net.xdclass.sp.domain.Video" >

        <constructor-arg name="title" value="面试专题课程第一季"></constructor-arg>

    </bean>


    <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" >
        <property name="id" value="8" />
        <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
        <property name="video" ref="video"/>
    </bean>

 

 

 

 

第3集 实战Spring5.X List-Map类型的注入

简介:讲解spring的常见的注入方式-List-Map

<bean id="video" class="net.xdclass.sp.domain.Video" >

        <!--list类型注入-->
        <property name="chapterList">
            <list>
                <value>第一章SpringBoot</value>
                <value>第二章Mybatis</value>
                <value>第三章Spring</value>
            </list>
        </property>

        <property name="videoMap">
            <map>
                <entry key="1" value="SpringCloud课程"></entry>
                <entry key="2" value="面试课程"></entry>
                <entry key="3" value="javaweb课程"></entry>
            </map>
        </property>
</bean>



public class Video {

    private int id;

    private String title;


    private List<String> chapterList;


    private Map<Integer,String> videoMap;

//省略set get方法
}

 

 

第4集 玩转spring ioc容器Bean之间的依赖和继承

简介:讲解spring里面bean的依赖和继承

<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">

        <property name="id" value="9"/>
        <property name="title" value="Spring 5.X课程" />

</bean>


<bean id="video2" class="net.xdclass.sp.domain.Video2" scope="singleton" parent="video">

        <property name="summary" value="这个是summary"></property>

</bean>
<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton">

        <property name="id" value="9"/>
        <property name="title" value="Spring 5.X课程" />

</bean>

<!--设置两个bean的关系,video要先于videoOrder实例化-->

<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" depends-on="video">
        <property name="id" value="8" />
        <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
        <property name="video" ref="video"/>
</bean>

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十二章 玩转Spring5.X bean 的生命周期和二次处理

 

第1集 玩转spring ioc容器Bean的生命周期的init和destroy方法

简介:讲解spring里面bean的生命周期里面的init和destroy方法

<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton" init-method="init" destroy-method="destroy">

        <property name="id" value="9"/>
        <property name="title" value="Spring 5.X课程" />

</bean>



public static void main(String [] args){

  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");



  ((ClassPathXmlApplicationContext) context).registerShutdownHook();

 }

 

第2集 bean的二次加工-Spring5.x后置处理器 BeanPostProcessor

简介:讲解Spring的BeanPostProcessor使用

public class CustomBeanPostProcessor implements BeanPostProcessor,Ordered {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        System.out.println("CustomBeanPostProcessor1 postProcessBeforeInitialization beanName="+beanName);

        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("CustomBeanPostProcessor1 postProcessAfterInitialization beanName="+beanName);
        return bean;
    }


    public int getOrder() {
        return 1;
    }
}

 

 

 

第3集 Spring5.X bean自动装配Autowire 属性

简介:讲解Spring的Bean的自动装配属性autowire

<!--<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="byName">-->
<!--<bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="byType">-->
    <bean id="videoOrder" class="net.xdclass.sp.domain.VideoOrder" autowire="constructor">

        <property name="id" value="8" />
        <property name="outTradeNo" value="23432fnfwedwefqwef2"/>
    </bean>

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十三章 高级知识点-玩转Spring5.X 面向切面编程 AOP

第1集 什么是AOP面向切面编程

简介:讲解什么是AOP面向切面编程

 

43914986b160ebe5baa089741cce70c1

 

 

第2集 掌握AOP面向切面编程核心概念

简介:讲解AOP面向切面编程相关核心概念

 

328ea34091cf9123ccd0a81156f3a09b

 

 

 

5043d3c2c64b20d375c5f6ac73592e6d

 

第3集 AOP里面的通知Advice类型讲解

简介:讲解AOP里面Advice通知的讲解

第4集 举个通俗的栗子-AOP面向切面编程

简介:举个栗子理解AOP面向切面编程

第5集 Spring5.X AOP切入点表达式讲解

简介:讲解Spring5.X的AOP切入点表达式

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十四章 Spring AOP里面的代理知识你知道多少

第1集 你知道动态代理和静态代理吗

简介:讲解静态代理和动态代理

 

 

第2集 代理模式实战之静态代理讲解

简介:讲解静态代理优缺点和实操

public class StaticProxyPayServiceImpl implements PayService {

    private PayService payService;

    public  StaticProxyPayServiceImpl(PayService payService){
        this.payService = payService;
    }

    public String callback(String outTradeNo) {

        System.out.println("StaticProxyPayServiceImpl callback begin");

        String result = payService.callback(outTradeNo);

        System.out.println("StaticProxyPayServiceImpl callback end");

        return result;
    }

    public int save(int userId, int productId) {

        System.out.println("StaticProxyPayServiceImpl save begin");

        int id = payService.save(userId, productId);

        System.out.println("StaticProxyPayServiceImpl save end");

        return id;
    }
}

 

第3集 AOP的实现策略之JDK动态代理

简介:讲解AOP常见的实现的策略JDK动态代理

 

定义一个java.lang.reflect.InvocationHandler接口的实现类,重写invoke方法

//Object proxy:被代理的对象  
//Method method:要调用的方法  
//Object[] args:方法调用时所需要参数  
public interface InvocationHandler {  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;  
}  
public class JdkProxy implements InvocationHandler {

    //目标类
    private Object targetObject;

    //获取代理对象
    public Object newProxyInstance(Object targetObject){
        this. targetObject = targetObject;

        //绑定关系,也就是和具体的哪个实现类关联
        return  Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(),this);
    }


    public Object invoke(Object proxy, Method method, Object[] args) {


        Object result = null;

        try{
            System.out.println("通过JDK动态代理调用 "+method.getName() +", 打印日志 begin");

            result = method.invoke(targetObject,args);

            System.out.println("通过JDK动态代理调用 "+method.getName() +", 打印日志 end");

        }catch (Exception e){

            e.printStackTrace();
        }

        return result;


    }
}

 

第4集 AOP的实现策略之CGLib动态代理

简介:讲解AOP常见的实现的策略JDK动态代理

 

public class CglibProxy  implements MethodInterceptor {

    //目标类
    private Object targetObject;

    //绑定关系
    public Object newProxyInstance(Object targetObject){
        this.targetObject = targetObject;

        Enhancer enhancer = new Enhancer();
        //设置代理类的父类(目标类)
        enhancer.setSuperclass(this.targetObject.getClass());

        //设置回调函数
        enhancer.setCallback(this);

        //创建子类(代理对象)
        return enhancer.create();
    }

    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        Object result = null;

        try{

            System.out.println("通过CGLIB动态代理调用 "+method.getName() +", 打印日志 begin");

            result = methodProxy.invokeSuper(o,args);

            System.out.println("通过CGLIB动态代理调用 "+method.getName() +", 打印日志 begin");

        }catch (Exception e){
            e.printStackTrace();
        }


        return result;
    }


}

第5集 CGLib动态代理和JDK动态代理总结

简介:总结CGlib和JDk动态代理

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十五章 面向切面编程 Spring AOP 实战 配置

 

第1集 基于Spring的AOP快速实现通用日志打印《上》

简介:实战SpringAOP配置日志打印基础准备

第2集 基于Spring的AOP快速实现通用日志打印《下》

简介:实战SpringAOP配置日志打印,配置切面和织入

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十六章 玩转Spring5.X Xml配置转换到注解配置

 

第1集 论Spring使用方式之XML和注解的优缺点

简介:讲解Spring使用xml和注解的优缺点

 

 

第2集 实战Spring5.X的注解配置项目

简介:讲解spring的使用注解配置项目

public static void main(String[] args) {


     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        //扫描指定的包,包括子包
        context.scan("net.xdclass");


        //里面完成初始化操作,核心方法
        context.refresh();


        VideoService videoService = (VideoService) context.getBean("videoService");
        videoService.findById(2);


        Video video = (Video) context.getBean("video");
        video.init();
    }

 

 

 

 

第3集 实战Spring5.X的常用注解和xml对比《上》

简介:讲解spring的xml和注解对比《上》

 

 

第4集 实战Spring5.X的常用注解和xml对比《下》

简介:讲解spring的xml和注解对比《上》

 

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十七章 玩转Spring5.X Xml配置转换到注解配置进阶

 

 

第1集 spring的@Configuration和@Bean注解定义第三方bean

简介:讲解@Configuration和@Bean注解的使用

 

@Configuration
public class AppConfig {

    //使用@bean注解,表明这个bean交个spring 进行管理
    // 如果没有指定名称,默认采用 方法名 + 第一个字母小写 作为bean的名称
    @Bean(name = "videoOrderName",initMethod = "init",destroyMethod = "destroy")
    @Scope
    public VideoOrder videoOrder(){
        return new VideoOrder();
    }

}

 

 

 

第2集 Spring的自动映射配置文件PropertySource注解讲解

简介:讲解@PropertySource注解的使用

@Configuration
@PropertySource(value = {"classpath:config.properties"})
public class CustomConfig {

    @Value("${server.host}")
    private String host;

    @Value("${server.port}")
    private int port;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

 

 

 

logo **愿景:"让编程不再难学,让技术与生活更加有趣"

第二十八章 案例实战之基于Spring注解配置AOP面向切面编程

 

第1集 Spring AOP注解基础准备

简介:讲解Spring AOP注解的基础准备

 

@Component
//告诉spring,这个一个切面类,里面可以定义切入点和通知
@Aspect
public class LogAdvice {


    //切入点表达式
    @Pointcut("execution(* net.xdclass.sp.service.VideoServiceImpl.*(..))")
    public void aspect(){

    }

    //前置通知
    @Before("aspect()")
    public void beforeLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  beforeLog");
    }


    //后置通知
    @After("aspect()")
    public void afterLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  afterLog");
    }

}

 

 

第2集 开启Spring AOP注解配置和扫描

简介:开启Spring AOP注解和扫描

@Configuration
@ComponentScan("net.xdclass")
@EnableAspectJAutoProxy  //开启了spring对aspect的支持
public class AnnotationAppConfig {

}

 

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAppConfig.class);

        VideoService videoService = (VideoService) context.getBean("videoService");

        videoService.findById(2);

}

 

@Component
//告诉spring,这个一个切面类,里面可以定义切入点和通知
@Aspect
public class LogAdvice {

    //切入点表达式,也可以直接在通知上编写切入点表达式
    @Pointcut("execution(* net.xdclass.sp.service.VideoServiceImpl.*(..))")
    public void aspect(){

    }

    //前置通知
    //@Before("aspect()")

    @Before("execution(* net.xdclass.sp.service.VideoServiceImpl.*(..))")
    public void beforeLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  beforeLog");
    }


    //后置通知
    @After("aspect()")
    public void afterLog(JoinPoint joinPoint){
        System.out.println("LogAdvice  afterLog");
    }

}

 

 

 

第3集 AOP案例实战之环绕通知统计接口耗时

简介:通过AOP的环绕通知统计方法调用耗时

 /**
     * 环绕通知
     * @param joinPoint
     */
    @Around("aspect()")
    public void around(JoinPoint joinPoint){

      Object target = joinPoint.getTarget().getClass().getName();
        System.out.println("调用者="+target);

        //目标方法签名
        System.out.println("调用方法="+joinPoint.getSignature());

        //通过joinPoint获取参数
        Object [] args = joinPoint.getArgs();
        System.out.println("参数="+args[0]);
        
        
        long start = System.currentTimeMillis();
        System.out.println("环绕通知 环绕前=========");

        //执行连接点的方法
        try {
            ((ProceedingJoinPoint)joinPoint).proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        long end = System.currentTimeMillis();
        System.out.println("环绕通知 环绕后=========");

        System.out.println("调用方法总耗时 time = " + (end - start) +" ms");
    }

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

第二十九章 新版SSM整合-打通Mysql数据库控制事务(包含面试题)

 

第1集 Spring 常见的事务管理-面试常考点

简介:讲解Spring常见的事务管理

* 代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,通过TransactionTempalte手动管理事务(用的少)

  * 通过AOP实现,可配置文件方式或者注解方式实现事务的管理控制(用的多)

 

 

 

第2集 Spring事务的传播属性和隔离级别

简介:讲解Spring事务的传播属性和隔离级别

 

 

 

 

 

 

第3集 新版SpringBoot-Spring-Mybatsi事务控制讲解

简介:新版SSM @Transactional 事务控制讲解

 

第4集 新版SpringBoot-Spring-Mybatsi课程总结和后续内容预告

简介:新版SSM课程总结和后续内容预告

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

手机端-小滴课堂在线教育系统效果演示和技术准备

 

第1集 小滴课堂在线教育项目效果演示

简介:演示手机端小滴课堂在线教育项目

 

 

第2集 轻量级-小滴课堂核心数据库表字段设计和测试数据准备

简介:设计轻量版-在线教育的核心库表结构

 

 

第3集 新版SSM-SpringBoot2.X 后端项目框架搭建

简介:新版SSM- Springboot2.X+Spring5.x + Mybatis3.X项目创建和依赖准备

 

 

第4集 小滴课堂综合实战-项目相关包和实体类创建

简介:创建相关的包和项目用的实体类

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂项目实战之打通Myabtis连接Mysql开发视频列表

 

第1集 小滴课堂实战之Mybaits打通Mysql数据库

简介:配置Mybatis连接Mysql数据库

 

 

第2集 小滴课堂实战之视频列表接口开发+API权限路径规划

简介:开发视频列表JSON接口

第3集 小滴课堂实战之dev-tool 实现IDEA项目热部署

简介:使用dev-tool实现热部署

 

 

 

第4集 小滴课堂实战之首页banner轮播图和视频详情接口开发

简介:首页banner轮播图接口开发

 

 

第5集 小滴课堂实战之视频详情接口开发-三表关联查询映射

简介:视频详情接口,多表关联开发

 

 

第6集 小滴课堂实战之自定义异常开发和配置

简介:开发自定义异常和配置

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂项目实战之用户注册登录模块和JWT登录解决方案

 

第1集 小滴课堂实战之用户注册功能开发和MD5加密工具类封装

简介:用户注册功能接口开发

 

 

 

第2集 常见的互联网项目中 单机和分布式应用的登录校验解决方案

简介:讲解单机和分布式应用下登录校验,session共享,分布式缓存使用

 

image-20200417222658225

 

 

 

 

 

 

第3集 分布式应用下登录检验解决方案 JWT讲解

简介:分布式应用的登录检验解决方案 JWT讲解 json wen token

 

 

第4集 登录校验Json Web Token实战之封装通用方法

讲解:引入相关依赖并开发JWT工具类, 开发生产token和校验token的办法

 

第5集 小滴课堂实战之登录模块开发整合Json Web Token

简介:开发登录模块功能,并整合JSON Web Token

 

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂项目实战之登录拦截器开发和订单模块开发

 

第1集 小滴课堂实战之用户登录校验拦截器开发

简介:开发对应的登录拦截器

 

 

第2集 小滴课堂实战之loginInterceptor注册和放行路径

简介:loginInterceptor 拦截器注册和路径校验配置

/**
 * 拦截器配置
 *
 * 不用权限可以访问url    /api/v1/pub/
 * 要登录可以访问url    /api/v1/pri/
 */

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {


    @Bean
    LoginInterceptor loginInterceptor(){
        return new LoginInterceptor();
    }


    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //拦截全部
        registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/v1/pri/*/*/**")
                //不拦截哪些路径   斜杠一定要加
                .excludePathPatterns("/api/v1/pri/user/login","/api/v1/pri/user/register");

        WebMvcConfigurer.super.addInterceptors(registry);

    }
}

 

 

 

第3集 小滴课堂实战之个人信息查询接口开发

简介:根据token查询个人信息接口开发

 

 

 

第4集 小滴课堂实战之VideoOrder下单模块开发

简介:开发用户下单购买视频接口

 

 

 

第5集 小滴课堂实战之播放记录表设计和模块开发

简介:播放记录表设计和功能模块开发

 

第6集 小滴课堂实战之订单和播放记录事务控制

简介:播放记录表和下单整合,开启事务控制

 

 

 

第7集 小滴课堂实战之订单列表接口开发

简介:订单列表接口开发

   /**
     * 订单列表
     * @param request
     * @return
     */
    @GetMapping("list")
    public JsonData listOrder(HttpServletRequest request){
        Integer userId = (Integer) request.getAttribute("user_id");

        List<VideoOrder> videoOrderList = videoOrderService.listOrderByUserId(userId);

        return JsonData.buildSuccess(videoOrderList);

    }
    
    
    
    <select id="listOrderByUserId" resultType="VideoOrder">

        select * from video_order where user_id=#{user_id} order by create_time desc

    </select>

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

性能优化实战之协议优化和引入Guava缓存

 

 

第1集 小滴课堂实战之接口协议调整和日期格式

简介:调整api接口协议和日期格式

 

第2集 高并发项目必备利器之分布式缓存和本地缓存

简介: 讲解分布式缓存和本地缓存知识

 

 

 

 

 

 

第3集 谷歌开源缓存框架Guava Cache讲解和封装缓存组件

简介: 讲解谷歌开源框架Guava Cache,封装API

 

 

 

第4集 小滴课堂实战之轮播图接口引入本地缓存

简介: 轮播图接口引入本地缓存

         try{

            Object cacheObj =  baseCache.getTenMinuteCache().get(CacheKeyManager.INDEX_BANNER_KEY, ()->{

                List<VideoBanner> bannerList =  videoMapper.listVideoBanner();

                System.out.println("从数据库里面找轮播图列表");

                return bannerList;

            });

            if(cacheObj instanceof List){
                List<VideoBanner> bannerList = (List<VideoBanner>)cacheObj;
                return bannerList;
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;

 

 

 

第5集 小滴课堂实战之视频列表引入本地缓存

简介: 视频列表引入本地缓存

 

 

第6集 小滴课堂实战之视频详情引入本地缓存

简介: 视频详情引入本地缓存

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

压力测试工具Jmeter5.X快速入门实战

 

第1集、接口压测和常用压力测试工具对比

简介:目前用的常用测试工具对比

 

第2集 压测工具本地快速安装Jmeter5.x

简介:GUI图形界面的安装 Jmeter5.x

 

 

第3集 Jmeter5.x目录文件讲解和汉化操作

简介:讲解jmeter解压文件里面的各个目录,文件等

 

 

第4集 Jmeter5.X基础功能组件介绍线程组和Sampler

简介:讲解Jmeter里面GUI菜单栏主要组件

 

 

第5集 Jmeter5.x实战之压测结果聚合报告分析

简介:讲解压测结果的聚合报告

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

实战接口压力测试,明白优化前后的QPS并发差距和跨域配置

 

第1集 开启Guava缓存压测热点数据接口

简介: 启用缓存 压测热点数据接接口

 

 

 

第2集 取消Guava缓存压测热点数据接口和前后对比

简介: 不启用缓存 压测热点数据接口

 

第3集 SpringBoot2.X开启跨域配置

简介: 什么是浏览器跨域和springboot怎么解决

     1)JSONP
     2)Http响应头配置允许跨域
             nginx层配置 https://www.cnblogs.com/hawk-whu/p/6725699.html
     3)程序代码中处理 SpringBoot 通过拦截器配置
     
      //表示接受任意域名的请求,也可以指定域名
     response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
     
     //该字段可选,是个布尔值,表示是否可以携带cookie
     response.setHeader("Access-Control-Allow-Credentials", "true");
     
     response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
     
     response.setHeader("Access-Control-Allow-Headers", "*");

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

全栈工程师必备VSCODE编辑器和开发环境搭建

 

第1集 前端主流编辑器VSCode安装

简介:前端编辑器vscode安装

 

 

 

第2集 互联网公司前端开发环境搭建之Node和Npm介绍

简介:搭建node环境和npm安装

 

 

 

node -v 
npm -v 

 

第3集 切换npm镜像源为淘宝npm镜像

简介:修改npm镜像源为国内

淘宝 NPM 镜像是一个完整 npmjs.org 镜像,可以用此代替官方版本。

使用淘宝定制的 cnpm 命令行工具代替默认的 npm:(需要管理员权限)

npm install -g cnpm --registry=https://registry.npm.taobao.org

这样就可以使用 cnpm 命令来安装模块了:

cnpm install [name]

更多信息可以查阅:https://developer.aliyun.com/mirror/NPM

 

 

第4集 新版Vue + 脚手架Vue-Cli 4.3 安装

简介:本地搭建Vue 、CLI、Cube-UI相关框架

 

第5级 VsCode导入小滴课堂前端项目

简介:使用VSCODE导入小滴课堂前端项目

 

{
    "emmet.syntaxProfiles": {
           "vue-html": "html",
           "vue": "html"
    },
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        "html",
        "vue"
    ],
    "eslint.options": {
        "plugins":["html"]
    }
}

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

全栈工程师必备之新版Vue2.6 急速掌握核心内容

第1集 新版VueCli 4.3创建vue项目

简介:使用vue cli 4.3创建vue项目

 

第2集 新版Vue快速入门之Vue指令和参数

简介:讲解什么是Vue指令

 

 

第3集 新版Vue快速入门之v-if 和v-else条件指令

简介:讲解新版Vue条件指令

<div id="app">

        <div v-if="Math.random() > 0.5 "> 大于0.5  </div>

        <div v-else>小于0.5  </div>
        
</div>


<script>
        new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{

            },

            //自定义方法
            methods: {
                
            }
        })
</script>

 

第4集 新版Vue快速入门之v-for 循环指令

简介:讲解新版Vue的v-for 循环指令

<div id="app">

        <ol>
            <li v-for=" user in users "> 
                {{user.name}}
            </li>
        </ol>
</div>
<script>
        new Vue({
            //绑定到哪个元素
            el:'#app',
            //数据源
            data:{
                users:[
                    {name: "Anna小姐姐"},
                    {name: "老王"},
                    {name: "二当家小D"},
                ]
            },
            //自定义方法
            methods: {
                
            }
        })
</script>

 

第5集 新版Vue快速入门之v-model

简介:讲解新版Vue的v-model

    <div id="app">

       <p> {{phone}} </p>
       手机号 <input v-model="phone"  />
        
    </div>

    <script>
        new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{
                phone : "000"
            },

            //自定义方法
            methods: {
                
            }
        })
    </script>

第6集 新版Vue快速入门之v-on监听事件

简介:讲解新版Vue的v-on指令 监听事件

<div id="app">


        <p> {{title}} </p>
       
        <button v-on:click="changeTitle"> 完善标题 </button>
        
    </div>


    <script>
        new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{

              title: "面试专题课程"

            },

            //自定义方法
            methods: {
                changeTitle:function(){
                    this.title = "||小滴课堂 2020年 " + this.title;
                }

            }
        })
    </script>

 

 

第7集 Vue常见缩写 v-bind和v-on讲解

简介:vue常见缩写v-bind和v-on讲解

 

  <div id="app">


        <p> {{title}} </p>
       
        <button @click="changeTitle"> 完善标题 </button>
        <p/>
        <a :href="url" > 点击跳转 </a>

    </div>


    <script>
        new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{

              title: "面试专题课程",
              url : "https://xdclass.net"

            },

            //自定义方法
            methods: {
                changeTitle:function(){
                    this.title = "||小滴课堂 2020年 " + this.title;
                }

            }
        })
    </script>

 

 

第8集 新版Vue快速入门之component组件

简介:讲解vue里面的组件

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

    </div>
    <script>
    Vue.component('xd_component',{
        data:function(){
            return {
                count: 0
            }
        },
        template:' <button v-on:click="count++">  点击 {{count}}次  </button> '
    })
        new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{
            },

            //自定义方法
            methods: {

            }
        })
    </script>

第9集 新版Vue快速入门之prop向子组件传值

简介:讲解vue里面通过prop向子组件传值

 <div id="app">
       
        <xd_component message="小滴课堂 https://xdclass.net"></xd_component>

        <xd_component message="面试专题"></xd_component>

</div>



<script>

    Vue.component('xd_component',{
       
       props:{
           message:{
               type:String
           }
       },
       data:function(){
        return {
            count : 0
        }
       },
       //组件里面的template只能包含一个根节点
        template:'<div> <button v-on:click="count++"> {{message}}  点击 {{count}}次  </button> </p> </div> '

    })


   new Vue({
            //绑定到哪个元素
            el:'#app',

            //数据源
            data:{

            },

            //自定义方法
            methods: {

            }
        })
</script>

 

<xd_component message="小滴课堂 https://xdclass.net" v-bind:XXXX></xd_component>
或缩写
<xd_component message="小滴课堂 https://xdclass.net" :XXXX></xd_component>

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目技术栈介绍和ES6知识点补充

 

第1集小滴课堂前端项目技术组件概述

简介:常见的技术组件的作用

 

 

第2集 ECMAScript 6常见语法快速入门《上》

简介:讲解ES6里面常见的语法上集

 

第3集 ECMAScript 6常见语法快速入门《下》

简介:讲解ES6里面常见的语法下集

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

全栈工程师之小滴课堂前端项目架构搭建

 

第1集 VueCli 4.3搭建小滴课堂前端项目架构

简介:使用 VueCli 4.3搭建小滴课堂前端项目架构

 

第2集 小滴课堂前端项目目录结构创建和讲解

简介:小滴课堂前端项目目录结构创建和讲解

 

第3集 基于浏览器和node.js的http客户端Axios讲解

简介:基于浏览器和node.js的http客户端Axios讲解

 

 

 

第4集 Axios封装通用后端请求API模块

简介:使用axios封装请求后端api接口

import axios from '../request'

//注册接口
export const registerApi = (phone, pwd , name)=> axios.post("/api/v1/pri/user/register",{
    "phone":phone,
    "pwd":pwd,
    "name":name
})

//登录接口
export const loginApi = (phone, pwd) => axios.post("/api/v1/pri/user/login",{
    phone,
    pwd
})


//轮播图接口
export const getBanner = () => axios.get("/api/v1/pub/video/list_banner")

//视频列表接口
export const getVideoList = ()=> axios.get("/api/v1/pub/video/list")


//视频详情
export const getVideoDetail = (vid)=> axios.get("/api/v1/pub/video/find_detail_by_id?",{
    params: {
        video_id:vid
    }
})

//下单接口
export const saveOrder = (token, vid)=>axios.post("/api/v1/pri/order/save",{
    "video_id":vid
},{
    headers:{
        "token":token
    }
})

//订单列表
export const getOrderList = (token)=>axios.get("/api/v1/pri/order/list",{
    params:{
        "token":token
    }
})

//用户信息接口
export const getUserInfo = (token)=>axios.get("/api/v1/pri/user/find_by_token",{
    params:{
        "token":token
    }
})

 

 

第5集 Vue-Router开发小滴课堂前端项目路由

简介:Vue-Router开发小滴课堂前端项目路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home/Home.vue'
import CourseDetail from '../views/CourseDetail/CourseDetail.vue'
import Login from '../views/Login/Login.vue'
import Order from '../views/Order/Order.vue'
import Pay from '../views/Pay/Pay.vue'
import Personal from '../views/Personal/Personal.vue'
import Register from '../views/Register/Register.vue'


Vue.use(VueRouter)

  const routes = [
    {
      path:"/",
      name:"Home",
      component:Home
    },
    {
      path:"/coursedetail",
      name:"CourseDetail",
      //按需加载
      component : ()=>import("../views/CourseDetail/CourseDetail.vue")
      //component:CourseDetail
    },
    {
      path:"/login",
      name:"Login",
      component:Login
    },
    {
      path:"/order",
      name:"Order",
      component:Order
    },{
      path:"/pay",
      name:"Pay",
      component:Pay
    },{
      path:"/personal",
      name:"Personal",
      component:Personal
    },{
      path:"/register",
      name:"Register",
      component:Register
    },
  ]

const router = new VueRouter({
  routes
})

export default router

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目实战之通用底部选项卡CommonsFooter开发

 

第1集 怎样通过看Cube-UI官方文档和底部选项卡组件讲解

简介:学会看cube-ui文档,并掌握cube-tab-bar开发

 

第2集 小滴课堂移动端cube-tab-bar选项卡开发《上》

简介:开发小滴课堂底部选项卡cube-tab-bar

<template>
  <div class="tab">
    <cube-tab-bar v-model="selectedLabelSlots" @click="changHandler">
      <cube-tab
        v-for="(item) in tabs"
        :icon="item.icon"
        :label="item.label"
        :key="item.path"
        :value="item.path"
      ></cube-tab>
    </cube-tab-bar>
  </div>
</template>
<script>
export default {
  data() {
    return {
      selectedLabelSlots: "/",
      tabs: [
        {
          label: "首页",
          icon: "cubeic-home",
          path: "/"
        },
        {
          label: "我的订单",
          icon: "cubeic-like",
          path: "/order"
        },
        {
          label: "个人中心",
          icon: "cubeic-person",
          path: "/personal"
        }
      ]
    };
  }
};
</script>  

 

 

第3集 小滴课堂移动端cube-tab-bar选项卡开发《下》

简介:开发小滴课堂底部选项卡cube-tab-bar 下

  methods: {
      changHandler(path){
          //this.$route.path是当前路径
          if(path !== this.$route.path){
              this.$router.push(path)
          }
      }
  },
//vue实例生命周期 created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图
//vue实例生命周期 mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行额外的操作    //https://cn.vuejs.org/v2/guide/instance.html#%E5%AE%9E%E4%BE%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90
  created(){
      //默认路由选择器,比如刷新页面,需要重新进到当前路由
      this.selectedLabelSlots = this.$route.path
  }
<!--SCSS是一种CSS预处理语言, scoped 是指这个scss样式 只作用于当前组件-->
<style lang="scss" scoped>
.tab {
  position: fixed;
  bottom: 0;
  z-index: 999;
  background-color:#fff;
  width: 100%;
  border-top: 1px solid rgba($color: #000000, $alpha: 0.1);
} 
.cube-tab_active {
  color: #3bb149;
}
</style>

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目实战之首页轮播图和视频列表开发

第1集 小滴课堂首页Home模块开发

简介:小滴课堂首页Home模块开发

<template>
  <div>
    <!-- 轮播图组件 -->
    <!-- <home-banner :banners="banners"> </home-banner> -->
    <!-- 视频列表组件 -->
    <!-- <video-list :courselist="courselist"></video-list> -->
    <!-- 底部导航栏组件 -->
    <common-footer></common-footer>
  </div>
</template>

 

<template>
  <!--首页轮播图-->
  <!-- <home-banner></home-banner>
    
  <video-list> </video-list>-->

  <common-footer></common-footer>
</template>


<script>
import HomeBanner from "./Component/Banner";
import VideoList from "./Component/VideoList";
import CommonFooter from "@/components/CommonFooter";
import { getBanner, getVideoList } from "@/api/getData.js";

export default {
  //注册组件
  components: {
    HomeBanner,
    VideoList,
    CommonFooter
  },
  //声明数据源
  data() {
    return {
      banners: [],
      videoList: []
    };
  },
  //定义方法
  methods: {

     // 获取轮播图数据
    async getBannerData() {
      try {
        const result = await getBanner();
        console.log(result);
        if (result.data.code == 0) {
          this.banners = result.data.data;
        }
      }catch(error){
          console.lo(error)
      }
    },

    //获取视频列表
    async getVList(){
        try{
            const result = await getVideoList();
            if (result.data.code == 0) {
                this.videoList = result.data.data;
            }
        }catch(error){
            console.lo(error)
        }
    }
  },
  mounted(){
      //页面渲染完成调用方法获取数据
      this.getBannerData();
      this.getVList()
  }
};
</script>


<style lang="scss" scope>
</style>

 

 

第2集 小滴课堂首页轮播图banner模块开发

简介:首页轮播图Banner模块开发

<template>
  <div>
    <cube-slide  :data="banners">
      <cube-slide-item
        v-for="(item, index) in banners"
        :key="index">

        <a :href="item.url">
          <img :src="item.img"  style="width:100%"/>
        </a>
      
      </cube-slide-item>
    </cube-slide>
  </div>
</template>

<script>
export default {
    //获取父组件传递过来的值
    props:{
        banners:{
            type:Array,
            required:true
        }
    }
};
</script>

<style lang="scss" scoped>
</style>

 

 

第3集 小滴课堂首页视频列表模块开发

简介:首页视频列表模块开发 和 router-link 参数讲解

<template>
  <div class="list-content">
    <div class="list">
      <!-- 遍历视频 -->
      <router-link
        :key="item.id"
        :to="{ path: '/coursedetail', query: { video_id: item.id } }"
        class="course"
        v-for="item in videoList"
      >
        <div class="item_img">
          <img :src="item.cover_img" />
        </div>
        <div class="video_info">
          <div class="c_title">{{ item.title }}</div>
          <div class="price">¥ {{ item.price / 100 }}</div>
        </div>
      </router-link>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    videoList: {
      type: Array,
      required: true,
    },
  },
}
</script>
<style lang="scss" scoped>
//列表包裹层边距
.list-content {
  margin-top: 20px;
  padding: 0 13px;
}
//视频包括层
.list {
  display: flex; //设置flex布局
  flex-wrap: wrap; //换行排列
  justify-content: space-between; //两端对齐
  padding-bottom: 55px;
}
//视频个体层
.course {
  width: 48%;
  margin-bottom: 17px;
}
//视频图片
.item_img {
  font-size: 0; //消除图片元素产生的间隙
  box-shadow: 0 4px 11px 0 rgba(43, 51, 59, 0.6); //设置图片阴影,rgba前三个参数是颜色编码,最后一个是透明度
  border-radius: 8px; //设置图片圆角
  img {
    width: 100%;
    border-radius: 8px;
  }
}
.c_title {
  //设置超过两行隐藏 start
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  word-break: break-all;
  //设置超过两行隐藏 end
  font-size: 11px;
  height: 26px;
  line-height: 13px;
  margin-top: 10px;
  color: #2b333b;
}
//价格
.price {
  margin-top: 8px;
  font-size: 12px;
  color: #d93f30;
}
</style>

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目实战之视频详情页模块开发

第1集 小滴课堂视频详情页基础模块开发

简介:小滴课堂CourseDetail基础模块开发

 

<script>
//引入组件
import DetailHeader from './Components/Header'
import DetailCourse from './Components/Course'
import DetailTab from './Components/Tab'

import { getVideoDetail } from "@/api/getData.js";


export default {
    //注册组件
    components:{
        DetailHeader,
        DetailCourse,
        DetailTab
    },

    data(){
        return {
            //视频信息
            vdieoInfo:{},
            //章集
            chapterList:[]
        }
    },

    methods:{
        //获取视频详情
        async getDetail(vid){
            try{
               const result =  await getVideoDetail(vid)
               if(result.data.code == 0){
                   this.vdieoInfo = result.data.data;
                   this.chapterList = result.data.data.chapter_list;
               }

            }catch(error){
                console.log(error)
            }
        }
    },

    mounted(){
        //渲染完成后拿数据
        console.log(this.$route.query.video_id)
        this.getDetail(this.$route.query.video_id);

    }
}
</script>

 

<template>
    <div>
        
        <!--顶部返回组件-->
        <detail-header ></detail-header>

        <!--视频介绍组件-->
        <!-- <detail-course></detail-course>

        <!--视频tab简介组件-->
        <detail-tab></detail-tab>

        <!--底部立刻购买-->
        <footer></footer> -->

    </div>
</template>

 

 

 

第2集 小滴课堂视频详情页Header子组件开发

简介:小滴课堂CourseDetail的Header子组件开发

 

<script>
export default {
    
    props:{
        vdieoInfo:{
            type:Object,
            required:true
        }
    }
}
</script>

 

<template>
    <div>
        <header>
            <div class="header">
                <span @click="$router.back(-1)"> <i class="cubeic-back"></i> </span>
                <div class="title">
                    {{vdieoInfo.title}}
                </div>
            </div>
        </header>

    </div>
</template>

 

<style lang="scss" scoped>
.header {
    display: flex;//flex左右布局
    background-color: #07111b;
    padding: 10px 20px;
    color: #fff;
}  
// 返回箭头
.cubeic-back {
    color: #fff;
    margin-right:5px;
}
//视频标题
.title {
    font-size: 16px;
    width: 80%;
    //超出省略
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}
</style>

 

第3集 小滴课堂视频详情页Course子组件开发

简介:小滴课堂CourseDetail的Course子组件开发

 

<script>
export default {
  //从父组件传内容过来
  props: {
    videoInfo: {
      type: Object,
      required: true
    }
  }
};
</script>

 

<template>
  <div class="c_wapper">
    <div class="course">
      <div class="l_img">
        <img :src="videoInfo.cover_img" :title="videoInfo.title" />
      </div>

      <div class="r_txt">
        
        <div class="txt">
          <span>综合评分:</span>
          <p>{{videoInfo.point}}</p>
        </div>

        <div class="txt">
          <span>价格:</span>
          <p>¥{{videoInfo.price /100}}</p>
        </div>
       
      </div>
    </div>
  </div>
</template>

 

<style lang="scss" scoped>
//包裹层
.c_wrapper {
    padding: 0 14px;
}
//视频信息包裹层
.course {
  margin:14px 0;
  display:flex;//设置flex,左右布局
}
//视频左边图片层
.l_img {
  height:88px;
  margin-right:14px;
  & img {
    height:100%;
    border-radius:15px;
  }   
}
// 视频右边文字包裹层
.r_txt {
    padding:6px 0;
    font-size:12px;
    flex:1;//设置1可自动伸缩占用剩余空间
}
//每行文字层(综合评分、价格)
.txt {
    // 设置flex让文字两端对齐
    display:flex;
    justify-content:space-between;
    line-height:16px;
    & p {
        text-align:center;
        width:40%;
        color:#3bb149;
    }   
    & i {
        color:#666;
        font-weight:bolder;
        width:60%;
        & span {
            color:#2b333b;
            font-size:12px;
        }
    }      
}
  
</style>

 

第4集 小滴课堂视频详情页tab子组件开发和vue动态组件讲解

简介:小滴课堂CourseDetail的tab子组件开发和vue的动态组件讲解

<script>
import Summary from './Summary'
import Catalog from './Catalog'

export default {

    components:{
        Summary,
        Catalog
    },

    props:{
        videoInfo:{
            type:Object,
            required:true
        },
        chapterList:{
            type:Array,
            required:true
        }

    },

    data(){
        return{
            selectedLabel:"简介",
            tabs:[
                {
                    label:"简介"
                },{
                    label:"目录"
                }
            ]
        }
    }
}
</script>
<template>
    
    <div>
        <cube-tab-bar v-model="selectedLabel" show-slider>
            <cube-tab v-for="item in tabs" :label="item.label" :key="item.label">
            </cube-tab>
        </cube-tab-bar>
        
        <component :videoInfo="videoInfo" :chapterList="chapterList" :is='selectedLabel==="简介"?"Summary":"Catalog" '>
        </component>
        
    </div>

</template>

 

第5集 小滴课堂视频详情页summary子组件开发

简介:小滴课堂CourseDetail的summary子组件开发

 

<script>
export default {
    props:{
        videoInfo:{
            type:Object,
            required:true
        }
    }
}
</script>

 

<template>
    <div> <img class="summary" :src="videoInfo.summary"/> </div>
</template>

 

<style lang="scss" scoped>
.summary {
  width:100%;
  padding-bottom:50px;
  margin:15px 0;
}
  
</style>

第6集 小滴课堂视频详情页Catalog目录子组件开发

简介:小滴课堂CourseDetail的Catalog目录子组件开发

 

<script>
export default {
    //从父组获取章集信息
    props:{
        chapterList:{
            type:Array,
            required:true
        }
    }

}
</script>

 

<template>
    <div class="cate_box">

        <div>
            <ul class="content" v-for="(item, ind) in chapterList" :key="item.id">
                    <h1> 第{{ind +1}}章 &nbsp;{{item.title}} </h1>

                    <li class="sub_cate" v-for="(item,subind) in chapterList[ind].episode_list" :key="item.id">
                    <span class="sub_title">{{ind+1}}-{{subind+1}} &nbsp;{{item.title}}  </span>    
                    </li>
            </ul>

        </div>

    </div>

</template>

 

<style lang="scss" scoped>
// 目录包裹层设置边距
.cate_box {
  padding: 0 15px 50px;
  background-color: #fff;
  margin: 15px 0;
}

//每一章包裹层
.content {
  padding: 10px;
  // 章标题
  & h1 {
    font-size: 16px;
    width: 100%;
    margin-bottom: 15px;
    font-weight: bolder;
    // 设置章标题过长,超过行宽度省略隐藏
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
}

//集包裹层
.sub_cate {
  font-size: 12px;
  padding: 10px 0;
  //集标题
  .sub_title {
    // 设置集标题过长,超过行宽度省略隐藏
    display: block;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }
}
</style>

 

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
</style>

第7集 小滴课堂视频详情页footer立刻购买按钮开发

简介:开发小滴课堂CourseDetail的footer立刻购买按钮

<!--底部立刻购买-->
<footer>
    <router-link :to="{path:'/pay',query:{video_id:this.$route.query.video_id}}" class="user_buy">
                <button>立刻购买</button>            
     </router-link>
</footer> 

 

<style lang="scss" scoped>
//底部
footer {
  // fixed固定在底部
  position: fixed;
  bottom: 0;
  width: 100%;
  padding: 8px 0;
  background-color: #fff;
  z-index: 999;
  box-shadow: 0 -2px 4px 0 rgba(0, 0, 0, 0.05);
}
//设置购买按钮样式
button {
  display: block;
  color: #fff;
  margin: 0 auto;
  background-color: #d93f30;
  height: 34px;
  line-height: 34px;
  border-radius: 17px;
  width: 80%;
  border: none;
  font-size: 15px;
  text-align: center;
}
</style>

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目实战之注册-登录-个人中心模块开发

 

第1集 小滴课堂前端用户模块之注册功能开发

简介:小滴课堂注册基础模块开发

<script>
//注册接口
import { registerApi } from "@/api/getData.js";
export default {
  data() {
    return {
      model: {
        phoneValue: "",
        pwdValue: "",
        nameValue: ""
      },
      fields: [ {
          type: "input",
          modelKey: "nameValue",
          label: "名称",
          props: {
            placeholder: "请输入名称"
          },
          rules: {
            required: true
          },
          messages: {
            required: "名称不能为空"
          }
        },
        {
          type: "input",
          modelKey: "phoneValue",
          label: "手机号",
          props: {
            placeholder: "请输入手机"
          },
          rules: {
            required: true
          },
          messages: {
            required: "手机号不能为空"
          }
        },
        {
          type: "input",
          modelKey: "pwdValue",
          label: "密码",
          props: {
            placeholder: "请输入密码",
            type: "password",
            eye: {
              open: false
            }
          },
          rules: {
            required: true
          },
          messages: {
            required: "密码不能为空"
          }
        }
       
      ]
    };
  },
  methods: {
    submitHandler(e, model) {
      e.preventDefault();
      //调用注册接口
      registerApi(model.phoneValue, model.pwdValue, model.nameValue).then(
        res => {
          if (res.data.code === 0) {
            const toast = this.$createToast({
              txt: "注册成功",
              type: "correct",
              time: 1500
            });
            toast.show();
          }
        }
      );
    }
  }
};
</script>

 

<template>
  <div class="main">
    <cube-form :model="model" @submit="submitHandler">
      
      <cube-form-group>
          <!--名称-->
        <cube-form-item :field="fields[0]"></cube-form-item>
        <!--手机号-->
        <cube-form-item :field="fields[1]"></cube-form-item>
        <!--密码-->
        <cube-form-item :field="fields[2]"></cube-form-item>
      </cube-form-group>


      <cube-form-group>
        <cube-button type="submit">注册</cube-button>
      </cube-form-group>


    </cube-form>
    <router-link to="/login" class="reg">登录</router-link> 
  </div>
</template>

 

<style lang="scss" scoped>
.main {
  padding: 50px 5% 0;
  text-align: center;
}
//注册
.cube-btn {
  margin-top: 20px;
}
// 登录
.reg {
  display: inline-block;
  margin-top: 30px;
  font-size: 18px;
}
</style>

 

 

第2集 小滴课堂前端用户模块之登录功能开发

简介:小滴课堂用户登录模块开发

<script>
//登录接口
import { loginApi } from "@/api/getData.js";
export default {
  data() {
    return {
      model: {
        phoneValue: "",
        pwdValue: ""
      },
      fields: [
        {
          type: "input",
          modelKey: "phoneValue",
          label: "手机号",
          props: {
            placeholder: "请输入手机"
          },
          rules: {
            required: true
          },
          messages: {
            required: "手机号不能为空"
          }
        },
        {
          type: "input",
          modelKey: "pwdValue",
          label: "密码",
          props: {
            placeholder: "请输入密码",
            type: "password",
            eye: {
              open: false
            }
          },
          rules: {
            required: true
          },
          messages: {
            required: "密码不能为空"
          }
        }
      ]
    };
  },
  methods: {
    submitHandler(e, model) {
      e.preventDefault();
      //调用注册接口
      loginApi(model.phoneValue, model.pwdValue).then(
        res => {
          if (res.data.code === 0) {
            //登录成功,跳转到个人中心
            localStorage.setItem('token',res.data.data)
            
            //跳转页面, 根据业务需要
            this.$router.push({path:'/'})

          }else{
             const toast = this.$createToast({
              txt: "登录失败",
              type: "error",
              time: 1500
            });
            toast.show();
          }
        }
      );
    }
  }
};
</script>

 

 

<template>
  <div class="main">
    <cube-form :model="model" @submit="submitHandler">
      
      <cube-form-group>
       
        <!--手机号-->
        <cube-form-item :field="fields[0]"></cube-form-item>
        <!--密码-->
        <cube-form-item :field="fields[1]"></cube-form-item>
      </cube-form-group>

      <cube-form-group>
        <cube-button type="submit">登录</cube-button>
      </cube-form-group>

    </cube-form>
    <router-link to="/register" class="reg">注册</router-link> 
  </div>
</template>

 

 

<style lang="scss" scoped>
.main {
  padding: 50px 5% 0;
  text-align: center;
}
// 登录
.cube-btn {
  margin-top: 20px;
}
//注册
.reg {
  display: inline-block;
  margin-top: 30px;
  font-size: 18px;
}
</style>

第3集 你知道vue里面的状态管理vuex吗?

简介:讲解vue里面的状态管理vuex模块

 

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: localStorage.getItem("token")
  },
  //同步修改state里面的值
  mutations: {
    SET_TOKEN:(state, token)=>{
      state.token = token
    }
  },

  //异步调用mutations里面的方法
  //contxt.commit 利用上下文触发mutations某个方法
  // vue代码里面 this.$store.dispatch触发action里面的定义的方法
  actions: {
    setToken(context,token){
      context.commit('SET_TOKEN',token)
    },

    clearToken(context){
      context.commit('SET_TOKEN','')
    }

  },
  modules: {
  }
})

 

 

 

第4集 小滴课堂前端用户模块之个人中心开发

简介:用户模块个人中心开发

 

<script>
import CommonFooter from "@/components/CommonFooter";
import { getUserInfo } from "@/api/getData.js";
import defaultHeadImg from "@/assets/logo.png";

export default {
  components: {
    CommonFooter
  },

  data() {
    return {
      info: {},
      defaultHeadImg: defaultHeadImg
    };
  },

  computed: {
    getToken() {
      return this.$store.state.token;
    }
  },

  methods: {
    //获取用户信息
    async getInfo() {
      try {
        const result = await getUserInfo(this.getToken);
        if (result.data.code === 0) {
          this.info = result.data.data;
        }
      } catch (error) {
        console.log(error);
      }
    },

    //退出登录
    async signOut() {
      //清除token
      await this.$store.dispatch('clearToken');
      localStorage.removeItem("token");

      //刷新页面
      location.reload();
    }
  },

  mounted() {
    if (this.getToken) {
      this.getInfo();
    }
  }
};
</script>

 

 

<template>
  <div>
    <div class="container">
        <div class="p_top">
            <div>
                <img :src='info.head_img || defaultHeadImg' alt="头像"/>
                <router-link to="/login" v-if = "getToken === ''"> 
                <p>立刻登录</p>
                </router-link>
                <p v-else>{{info.name}} </p>
            </div>
        </div>
        <button v-if="getToken !== ''" class="green" @click="signOut">
            退出登录
        </button>
    </div>
    <common-footer></common-footer>
  </div>
</template>

 

 

<style lang="scss" scoped>
.container {
  // 顶部头像区域
  .p_top {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px 0;
    background-color: #2c3f54;
    div {
      text-align: center;
      img {
        width: 60px;
        height: 60px;
        border-radius: 50px;
      }
      p {
        font-size: 16px;
        color: #fff;
        margin-top: 10px;
      }
    }
  }
}
// 退出登录
.green {
  display: block;
  background-color: #3bb149;
  border: none;
  outline: none;
  width: 80%;
  height: 40px;
  margin: 20px auto 0;
  color: #fff;
  border-radius: 20px;
}
</style>

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

小滴课堂前端项目实战之路由拦截和订单模块开发

 

 

第1集 小滴课堂前端项目实战之路由拦截功能开发

简介:前置守卫 路由拦截功能开发

//路由拦截,拦截全部路由,每次操作路由都是被拦截进行判断

router.beforeEach((to,from,next)=>{

  const token = localStorage.getItem("token");

  //筛选需要传token的路由,匹配route里面需要登录的路径,如果匹配到就是true
  if( to.matched.some(record => record.meta.requiresAuth) ){
    //根据token是否有,判断是否需要调到登录页面
    if(token){
      next()
    }else{
      next({path:'/login'})
    }
  }else{
    next();
  }

})

 

 

 

第2集 小滴课堂前端下单页面组件开发

简介:小滴课堂下单页面组件模块开发

<script>
import { getVideoDetail, saveOrder } from "@/api/getData.js";

export default {
  data() {
    return {
      videoinfo: {}
    };
  },
  methods: {
    //获取视频详情
    async getDetail(vid) {
      try {
        const result = await getVideoDetail(vid);
        if (result.data.code == 0) {
          this.videoinfo = result.data.data;
        }
      } catch (error) {
        console.log(error);
      }
    },

    //下单
    async pay() {
      try {
        const result = await saveOrder(
          this.$store.state.token,
          this.$route.query.video_id
        );

        if (result.data.code == 0) {
          const toast = this.$createToast({
            txt: "购买成功",
            type: "correct",
            time: 2000,
            onTimeout: () => {
              this.$router.push({ path: "order" });
            }
          });
          toast.show();
        }
      } catch (error) {
        console.log(error);
      }
    }
  },
  mounted() {
    this.getDetail(this.$route.query.video_id);
  }
};
</script>

 

<template>
  <div>
    <!--视频信息-->
    <div class="info">
      <p class="info_title">商品信息</p>
      <div class="box">
        <div class="imgdiv">
          <img alt="课程照片" :src="videoinfo.cover_img" />
        </div>
        <div class="textdiv">
          <p class="c_title">{{videoinfo.title}}</p>
          <p class="price">¥:&nbsp;&nbsp; {{(videoinfo.price / 100).toFixed(2)}}</p>
        </div>
      </div>
    </div>
    <!--顶部支付-->
    <div class="footer">
      <p class="money">实付:&nbsp;&nbsp; {{(videoinfo.price / 100).toFixed(2)}}</p>
      <p class="submit" @click="pay">立刻支付</p>
    </div>
  </div>
</template>

 

<style lang="scss" scoped>
// 视频标题
.info_title {
  padding: 10px 20px;
  background-color: #fff;
  border-bottom: 1px solid #d9dde1;
}

.box {
  background-color: #fff;
  box-sizing: border-box;
  padding: 20px;
  display: flex;
  margin-bottom: 15px;
  .imgdiv {
    width: 105px;
    height: 59px;
    flex-shrink: 0;
    img {
      width: 100%;
      height: 100%;
    }
  }

  .textdiv {
    margin-left: 20px;
    height: 59px;
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .price {
      flex-shrink: 0;
    }
  }
}
//底部
.footer {
  position: fixed;
  bottom: 0;
  width: 100%;
  height: 50px;
  background-color: #fff;
  display: flex;
  justify-content: space-between;
  box-shadow: 0 -2px 4px 0 rgba(0, 0, 0, 0.1);
  font-size: 16px;
  .money {
    height: 50px;
    line-height: 50px;
    flex: 2;
    text-align: center;
    background-color: #fff;
  }
  .submit {
    height: 50px;
    line-height: 50px;
    flex: 1;
    text-align: center;
    background-color: #ff2d50;
    color: #fff;
  }
}
</style>

 

 

 

第3集 小滴课堂前端订单列表模块开发

简介:小滴课堂前端订单列表组件模块开发

<script>

import CommonFooter from '@/components/CommonFooter'
import { getOrderList } from "@/api/getData.js";

export default {

    components:{
        CommonFooter
    },
    data(){
        return{
            orders:[]
        }
    },
    methods:{
        //获取订单列表
    async getOrderList(){
        try{
            const result =  await getOrderList(this.$store.state.token)
            if(result.data.code == 0){
                this.orders = result.data.data || []
            }

        }catch(error){
            console.log(error)
        } 
    }

    },
    mounted(){
        this.getOrderList();
    }
    
}
</script>

 

<template>
    <div class="main">
        <!--订单列表-->
        <div class="list" v-if="orders.length > 0">
            
            <div class="box" v-for="(item, index) of orders" :key="index">
                <router-link :to="{path:'/coursedetail', query:{ video_id : item.video_id }}">
                    <div class="smallbox">
                        
                        <div class="imgdiv">
                            <img :src="item.video_img" alt="小滴课堂课程图片"/>
                        </div>

                        <div class="textdiv">
                            <p class="title"> {{item.video_title}} </p>
                            <p class="price"> {{(item.total_fee / 100).toFixed(2)}}</p>
                        </div>

                    </div>
                </router-link>
            </div>

        </div>

        <div class="no_order" v-else>
            <p>暂未购买课程 </p>
        </div>

    <!--底部导航-->
        <common-footer></common-footer>

    </div>
</template>

 

<style lang="scss" scoped>
.list {
  padding: 0 20px;
}

// 视频个体
.box {
  padding: 20px 0;
  background-color: #fff;
  border-bottom: 1px solid #ddd;
  // 标题
  .title {
    font-size: 14px;
    margin-bottom: 15px;
  }
  // 订单详情
  .smallbox {
    //flex左右排列,两端对齐
    display: flex;
    justify-content: space-between;
    .imgdiv {
      width: 90px;
      height: 60px;
      flex-shrink: 0;
      img {
        width: 100%;
        height: 100%;
        border-radius: 10px;
      }
    }
    .textdiv p {
      margin-top: 10px;
      padding-left: 10px;
    }
  }
}

.no_order {
  margin-top: 50px;
  text-align: center;
}
</style>

 

第4集 小滴课堂前端项目开发总结回顾

简介:小滴课堂前端项目开发总结回顾

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

互联网公司 前端-后端项目云服务器生产环境部署核心知识

 

第1集 小滴课堂互联网架构之应用部署上线核心知识

简介:讲解应用部署到可以公网访问需要的知识

 

第2集 云服务器介绍和阿里云服务器ECS服务器选购

简介:什么是云服务器及目前主要的几个厂商介绍

 

第3集 阿里云服务器远程登录和常用工具

简介:讲解阿里云服务器登录使用和常见终端工具

​ ​

 

 

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

生产环境Linux CentOS云服务器常见相关软件安装

 

第1集 阿里云Linux服务器Centos7 安装JDK8环境

简介:Linux云服务器安装JDK1.8

第2集 生产环境Linux服务器上Nginx介绍和安装

简介:介绍什么是nginx服务器和快速安装

 

第3集 生产环境Linux服务器上Mysql安装和导入数据

简介:阿里云 Linux CentOS7 快速安装 Mysql

 

#下载mysql的Yum仓库
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

yum -y install mysql57-community-release-el7-10.noarch.rpm

#安装 mysql服务
yum -y install mysql-community-server

#启动数据库服务, systemctl 该命令可用于查看系统状态和管理系统及服务,centos7上开始使用
systemctl start  mysqld.service

#查看状态
systemctl status mysqld.service

#在日志文件中查看初始密码
grep "password" /var/log/mysqld.log

#进入修改Mysql密码

mysql -uroot -p

#新密码设置必须由大小写字母、数字和特殊符号组成
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Xdclass.net168';

#开启mysql的远程访问, %是指全部
grant all privileges on *.* to 'root'@'%' identified by 'Xdclass.net168' with grant option;

#刷新权限
flush privileges; 

 

小滴课堂综合项目实战-前端-后端集群部署线上Linux云服务器

 

第1集 前后端项目总体部署架构和阿里云域名解析A记录配置

简介:前端、后端项目总体部署架构和A记录配置

 

 

 

第2集 后端Java API项目阿里云服务器部署安装

简介:SpringBoot项目部署阿里云服务器

 

 

第3集 前后端分离-前端项目打包上传阿里云服务器

简介:前端项目打包上传阿里云服务器

 

第4集 线上部署之前端项目接入Nginx代理服务器

简介:讲解前后端应用部署和配置nginx访问

 

 

 

第5集 高可用处理之后端API多节点集群部署

简介:讲解springboot应用多节点部署和配置nginx访问

upstream lbs {
   server 112.74.55.160:8089;
   server 112.74.55.160:8088;
}
 location /api/ {
    proxy_pass http://lbs;
    proxy_redirect default;
}


​ #error_page 404 /404.html; ​
# redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

 

第6集 小滴课堂前端-后端项目阿里云服务器部署总结

简介:小滴课堂前端后端项目部署总结

 

logo 愿景:"让编程不再难学,让技术与生活更加有趣"

新版SSM课程零基础到项目实战总结和学习路线规划

 

第1集 新版SSM零基础到项目实战课程总结和学习路线推荐

简介:课程总结和学习路线建议

 

 

 

u=4073844855,1130410908&fm=26&gp=0

 

WechatIMG1

 

小滴课堂,愿景:让编程不在难学,让技术与生活更加有趣

相信我们,这个是可以让你学习更加轻松的平台,里面的课程绝对会让你技术不断提升

欢迎加小D讲师的微信: xdclass-lw

我们官方网站:https://xdclass.net

千人IT技术交流QQ群: 718617859

重点来啦:加讲师微信 免费赠送你干货文档大集合,包含前端,后端,测试,大数据,运维主流技术文档(持续更新)

https://mp.weixin.qq.com/s/qYnjcDYGFDQorWmSfE7lpQ