高级软件工程 课程总结

来源:互联网 发布:男人喜欢被舔么 知乎 编辑:程序博客网 时间:2024/06/06 05:04

学号:SA17225205    姓名:刘金福    

课程名称:《软件工程(C编码实践篇)》MOOC课程

课程连接: http://mooc.study.163.com/course/USTC-1000002006 ”

学习总结:

       孟老师的这个mooc课程再加上线下的课程和实验,是一个很不错的搭配,mooc上的课程主要讲了一些简单的,作为软件开发工程师需要具备的一些基本素养,可以说是起到了抛砖引玉的作用,我是一个跨考生,曾经学的是化学专业,可以说基础真的很薄弱,学很多门课程都其实蛮有压力的。孟老师的这个在线课程正好给我一个补基础的时候,尤其是一些程序员会用到的基本工具,比如git的学习,linux的命令操作,和代码风格的讨论。

       虽然线下的课程在一开始的时候上vue这样一个框架对于我来说会比较吃力,不过好在,老师在课程主页中想得很周到,把一些可能会遇到的基础的问题,都找到一些对应的解决方法的博客链接,整体来说学完vue会让我对框架这个概念有比较具体的理解,也让我学会了一些自学的基本方法。Vue后面介绍的restfull架构对我的触发很大,可以说,我在之前一直对一个程序的执行过程感到非常的神秘不可理解,对于计算机基础不是很好的人来说,一直会比较难理解的是关于程序顶层的东西非常陌生,不知道一个http请求到底是怎么被发送怎么被接收的,restfull框架让我明白面向对象的设计方法的好处,虽然这个框架不是重点介绍面向对象,但是结合着这个学期的很多课程,确实让我对面向对象有了更好的理解,是代码层面的理解,以前一直是一种概念上的感知,线上课程的那几个命令行小程序的设计,对数据和方法的一层层封装就是一种代码层面上的面向对象体现。

       最后的回调函数的概念,对我也很有启发,c语言中使用代码块来封装一个任务操作,可以作为函数参数被调用,让我更加的理解程序是对一个个任务的拆分和组装的过程,将一个大的功能拆分成小的任务来单独设计处理模块,然后将模块进行顺序的执行,最后就实现了一个大的功能。

       其实在课程的学习过程中曾经有很多的启发,现在记不起来了,对于一个初学者就是什么都是新鲜的,拿到一把锤子,因为不知道是用来敲钉子的,所以学会它来敲钉子都觉得是一种收获。在这里很感谢孟宁老师的用心教学,真的是一个很有想法和很有责任心的老师,尤其是在线下课堂上,以一种亦师亦友的态度和大家交流学习,这很让我感动,上课的虽然会经常讲到其他地方去,但是我感觉很多题外话都对我们很有启发。

从代码层面对软件工程的理解

             说实话 我没很明白该怎么描述这个问题。那我就简单说说个人的理解吧!
首先,代码还是老师醉开始强调的那个问题,好的代码必须有一定的代码风格和规范,要注释,但不累赘,要分行,但也看情况。比如注释,应该首先在变量和函数命名的时候就最好把要表达的意思在命名上体现,变量要用名词来组合,方法则多数以动词开头,且要熟练一些常用的词来命名。当程序比较复杂的时候,要给一些逻辑上比较难理解的语句或者方法做简单的注释,注释不必累赘,最好一句话解释清楚,注释最好另起一行
其次程序的代码最好在设计的时候就要进行模块化设计,可以按照功能来分模块,也可以按照业务的处理逻辑,处理对象来进行分模块,模块设计是为了程序高内聚低耦合,尽量减少模块之间的功能、逻辑、代码上的相互影响的情况。
  另外一个很重要的设计思想是程序可扩展,模块可重用,任何一个程序都是为了需求来设计的,而需求有可能会发生改变,当有新的需求增加的时候,要考虑到程序可方便扩展,不要推到重来。同时为了满足新的需求,原来设计的一些模块可以被重复使用,减少重新编程的工作量,这个就要求在程序设计之初就要考虑周全,比如数据库的设计就需要预留一些字段,可能目前不需要,但是也许为了的需求上需要用到,对应的在代码中,比如一些请求码的设计上也要预留一些给功能扩充使用,总之在程序中多写一些操作,也许将来就可以省很多工作,此外就是接口的设计一定要非常的合理,接口设计好了,怎么来实现,通过不同的实现来扩充不同的功能需求,这也是达到程序可扩充的一个重要手段。

历次实验报告连接:

Lab1: https://www.shiyanlou.com/courses/reports/1290447

Lab2: http://blog.csdn.net/liu896749150/article/details/78079409

Lab3: http://blog.csdn.net/liu896749150/article/details/78176433

Lab4http://blog.csdn.net/liu896749150/article/details/78524030

Lab5http://blog.csdn.net/liu896749150/article/details/78305300

Lab6http://blog.csdn.net/liu896749150/article/details/78440050


代码风格:

下面应用一篇博客中给的代码风格示例 

/*************************************************************** *Copyright (c) 2014,TianYuan *All rights reserved. * *文件名称: standard.h *文件标识: 编程规范示例代码 * *当前版本:V1.0 *作者:wuyq  *完成日期:20140709 * *修改记录1:   //修改历史记录,包括修改日期、版本号、修改人及修改内容等 *修改日期        版本号              修改人         修改内容 * -------------------------------------------------------------------------------------------------- * 20140709         V1.0                wuyq            创建 ******************************************************************/    #ifndef _STANDARD_H__  #define _STANDARD_H__    /*重定义一些基本数据类型*/  typedef char                s8;  typedef unsigned char       u8;  typedef signed short        s16;  typedef unsigned short      u16;  typedef int                 s32;  typedef unsigned int        u32;  typedef float               f32;  typedef signed long long    s64;  typedef unsigned long long  u64;  typedef enum {FALSE =0, TRUE =!FALSE} bool;    typedef bool BOOL;    /* 消息头 */  typedef struct {      u16     u16MsgType;         /* 消息类型*/      u16     u16MsgLength;       /*有效消息数据长度*/      u8      u8TransType;        /*传输通道0:网络 1:串口*/      u8      u8Reserved[3];      /*对齐*/  }STRU_MSG_HEAD;    /* 时间信息*/  typedef struct {      u16     u16Year;    /*年*/      u16     u16Month;   /*月*/      u8      u8Day;      /*日*/      u8      u8Hour;     /*时*/      u8      u8Minute;   /*分*/      u8      u8Second;   /*秒*/  }STRU_TIME_INFO;    /* MCM->Main 查询系统信息*/  struct  stru_machine_info_req {      STRU_MSG_HEAD   struMsgHeader;/*消息头*/  };    /* Main->MCM 反馈系统信息*/  struct stru_machine_info_rsp {      STRU_MSG_HEAD   struMsgHeader;/*消息头*/      f32             f32Temp;/*当前采样温度*/      f32             f32Vol;/*当前采样电压*/      f32             f32CpuFreq;/*Cpu频率*/      u32             u32FreeMem;/*剩余内存*/      u32             u32FreeDisk;/*剩余FLASH空间*/  };  /* Main向MCM返回软件升级结果 */  struct stru_software_update_rsp {      STRU_MSG_HEAD   struMsgHeader;      u8              b8Successful;/*是否升级成功*/      u8              u8Reserved[3];/*字对齐,保留*/  };    //函数头部的可采用如下的样式  /**********************************************************************  *功能描述:  *输入参数:  *输出参数:  *返回值:  *其它说明:  *修改记录1:   //修改历史记录,包括修改日期、版本号、修改人及修改内容等  *修改日期        版本号              修改人         修改内容  * --------------------------------------------------------------------------------------------------  * 20140709         V1.0                wuyq            创建  ***********************************************************************/    #endif  
/********************************************************************** *Copyright (c) 2014,TianYuan *All rights reserved. * * 文件名称: UnitTest.c * 文件标识:无 * 内容摘要:协议及单元测试示例代码 * 其它说明:无 * 当前版本: V1.0 * 作    者: wuyq * 完成日期: 20140709 * *修改记录1:   //修改历史记录,包括修改日期、版本号、修改人及修改内容等 *修改日期        版本号              修改人         修改内容 * -------------------------------------------------------------------------------------------------- * 20140709         V1.0                wuyq            创建 **********************************************************************/  #include <stdio.h>  #include <string.h>     // 重定义数据类型  typedef unsigned char       UINT8;  typedef unsigned short int    UINT16;  typedef unsigned int        UINT32;  typedef signed   int        INT32;     // 消息头结构  typedef struct  {      UINT16  iReserve1;      UINT16  iReserve2;      UINT16  iReserve3;      UINT16  iReserve4;  }MsgHead_T;     // 消息结构体(包含消息头和消息体)  typedef struct  {      MsgHead_T   MsgHead;                // 消息头      UINT32      iOperType;      // 操作类型, 操作类型只能为1或2      UINT8       szUserNumber[30];         // 用户号码      UINT8       szOperTime[20];      // 操作时间, 格式为: yyyymmdd      UINT32       iReserve1;                // 保留字段1      UINT8        szReserve2[50];           // 保留字段2  }UserReqMsg_T;     // 函数声明  INT32 ProcUserReqMsg(UserReqMsg_T *ptUserReqMsg);  INT32 main();     /********************************************************************** * 功能描述:主函数 * 输入参数:无 * 输出参数:无 * 返回值: 0-执行完毕 * 其它说明:无 * 修改日期        版本号              修改人         修改内容 * -------------------------------------------------------------------------------------------------- * 20140507         V1.0                zzx            创建 ***********************************************************************/  INT32 main()  {      UINT8  iRetVal          = 0;      UINT32 iOperType        = 0;        // 操作类型      UINT8  szUserNumber[30] = {0};      // 用户号码      UINT8  szOperTime[10]  = {0};    // 操作时间, 格式为: yyyymmdd         UserReqMsg_T tUserReqMsg = {0};     // 请求消息         // 对消息头部进行赋值      tUserReqMsg.MsgHead.iReserve1 = 1;      tUserReqMsg.MsgHead.iReserve2 = 2;      tUserReqMsg.MsgHead.iReserve3 = 3;      tUserReqMsg.MsgHead.iReserve4 = 4;         // 读入具体消息字段的值      printf("操作类型: \n");      scanf("%d", &iOperType);      printf("用户号码: \n");      scanf("%s", szUserNumber);      printf("操作时间: \n");      scanf("%s", szOperTime);         // 对具体消息字段进行赋值(保留字段可不赋值)      tUserReqMsg.iOperType = iOperType;      strncpy(tUserReqMsg.szUserNumber, szUserNumber, strlen(szUserNumber));// 获取号码, 用strncpy代替strcpy      strncpy(tUserReqMsg.szOperTime,   szOperTime,   strlen(szOperTime));     // 获取时间, 用strncpy代替strcpy         // 对消息体的字段进行异常判断      iRetVal = ProcUserReqMsg(&tUserReqMsg);  // 注意: 传递参数的时候要加上&      if (iRetVal == 0)      // 函数执行正确      {          // 打印消息字段内容          printf("The user request message is: iOperType=%d, szUserNumber=%s, szOperTime=%s.\n", tUserReqMsg.iOperType, tUserReqMsg.szUserNumber, tUserReqMsg.szOperTime);          return 0;      }      else         // 打印异常消息      {          printf("Some content of the user request message is wrong, please check!\n");          return -1;      }  }        /********************************************************************** * 功能描述:对消息体的字段进行异常判断 * 输入参数: ptUserReqMsg-用户请求消息 * 输出参数:无 * 返回值: 0-成功   其它-失败 * 其它说明:无 * 修改日期        版本号              修改人         修改内容 * -------------------------------------------------------------------------------------------------- * 20140507         V1.0                zzx            创建 ***********************************************************************/  INT32 ProcUserReqMsg(UserReqMsg_T *ptUserReqMsg)  {      INT32  iRetValue      = 0;         // 对输入参数进行异常判断      if (ptUserReqMsg == NULL)      {          printf("ProcUserReqMsg(...): input parameter(ptUserReqMsg) is NULL.\n");           return -1;      }         // 对消息体字段进行异常判断      if ((ptUserReqMsg->iOperType != 1) && (ptUserReqMsg->iOperType != 2))    // 操作类型只能为1或2, 其它为数据异常      {          printf("ProcUserReqMsg(...): the iOperType is wrong, iOperType=%d.\n", ptUserReqMsg->iOperType);          return -2;      }           if (strlen(ptUserReqMsg->szUserNumber) != 8) // 用户号码异常, 长度8位才正确      {          printf("ProcUserReqMsg(...): the szUserNumber is wrong.\n");           return -3;      }            if (strlen(ptUserReqMsg->szOperTime) != 8)  // 操作时间异常, 长度8位才正确      {          printf("ProcUserReqMsg(...): the szOperTime is wrong.\n");                 return -4;      }         return 0;  }  




笔记分享:

下面是在学习课程和实验的过程中个人笔记总结,不一定都对,是个人的一点理解

什么是Express?

1.   一个简单的express应用程序如下。

      var express = require('express');

          var app = express();

          app.get('/', function(req,res){

         res.send('hello world');

         console.log('hello world');

          });

          app.listen('8808');

2.     Express 就是一套nodejs 提供的接口。通过这个封装好的接口提供的一些方法就可以实现一个按照RESTful 框架设计的web应用了。

3.     基于vue的web应用,要想使用express来实现,就要在这个应用的build目录下的dev-server.js文件中实例化一个express对象,并给这个对象取名为app,同时给这个应用增加restful-server服务。


4.     而restful-server.js 也是build目录下创建的一个文件,这个文件定义了rest的一些服务


什么是RESTful?

1.     RESTful架构,是目前最流行的一种互联网软件架构。

2.     什么是互联网软件,就是基于浏览器来使用的软件,一种新型的软件。以前的软甲你都是基于单机的,以前的互联网的主要工作是提供主机之间的通信,现在的互联网是给互联网上的不同的主机提供一个服务器中提供的软件服务。

3.     所以为了软件能基于浏览器来提供服务,于是有了专门为此设计的架构,比较流行的就是RESTful架构

4.     REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。

所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。

所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。

5.     "资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。

"资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"Representation)。

比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。

URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述

6.     状态转化(State Transfer)

访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。(我们希望客户端操作后服务器端的数据会发生我们预期的变化)

互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。

客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GETPOSTPUTDELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

7.     综合上面的解释,我们总结一下什么是RESTful架构:

(1)每一个URI代表一种资源;

(2)客户端和服务器之间,传递这种资源的某种表现层;

   (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。


什么是vue-resource?

1、 vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。

2、 vue-resourceAPI分别有以下这些:
http get

http jsonp
http post
http put
http delete
resource get
resource save
resource update
resource remove
interceptor

3、 常用的就是get和post。

4、 引入vue-resource后,可以基于全局的Vue对象使用http,也可以基于某个Vue实例使用http。现在的项目中,基本上都是后者,因此在不同组件的beforeCreate或mounted钩子中取。在发送请求后,使用then方法来处理响应结果,then方法有两个参数,第一个参数是响应成功时的回调函数,第二个参数是响应失败时的回调函数。

 

// 基于全局Vue对象使用http

Vue.http.get('/someUrl',[options]).then(successCallback, errorCallback);

Vue.http.post('/someUrl',[body], [options]).then(successCallback, errorCallback);

                          

// 在一个Vue实例内使用$http

this.$http.get('/someUrl',[options]).then(successCallback, errorCallback);

this.$http.post('/someUrl',[body], [options]).then(successCallback, errorCallback);

 

5、 再简单介绍一下Promise对象:所谓Promise对象,就是代表了未来某个将要发生的事件(通常是一个异步操作)。它的好处在于,有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数

6、 ES6的Promise对象是一个构造函数,用来生成Promise实例。下面是Promise对象的基本用法。

var promise = new Promise(function(resolve, reject) {

  if (/* 异步操作成功 */){

    resolve(value);

  } else {

    reject(error);

  }

});

 

promise.then(function(value) {

  // success

}, function(value) {

  // failure

});

 

7、 我们再来分析例子中使用promise的例子。在actions.js里就使用到了。


new Promise 是创建一个promise实例对象。他像是一个构造函数,他的参数是一个函数,这个函数里执行了几条语句:

1 打印输出

2 调用axios的get方法,向服务器发送http 的get请求,然后将请求的response的data数据提交给mutations中定义的具体方法。

3打印输出

4 又是一个函数on_result 里面有几个语句,这个函数的执行是否有报错,也会被catch,然后打印错误。



什么是vue?

1.     Vue是个前端开发框架

2.     Vue程序需要使用nodejs运行(解析)。

3.     Vue的依赖模块需要使用cnpminstall来加载

4.     Npm run dev 启动程序

5.     在程序的目录的根级目录一般有一个index.html文件作为程序的入口界面。该界面一般是在body标签下挂在一个app程序,这个app程序就是程序逻辑代码的执行入口。这个app会在src文件下的main.js文件中被注册,其实就是一个vue框架的实例对象。

6.     该实例对象的名字叫做app,用el键来表示。“()”里面的可以看成是参数,Vue()就是调用vue的一个构造函数,传递了那么几个参数进去。通过new关键字,就构造出了一个vue的实例对象,名字是app。此外这个app对象还有一些参数,比如路由、组件等。

7.     Vue的入口可以通过routers.js文件进行配置路由。

8.     浏览器是通过url来访问我们的程序的,实际上他能访问到的内容就是我们提供的所有组件的内容,所以我们为每个url进行绑定组件,而绑定其实就是为每个路由指定组件在文件中的目录。通过上面的配置可以看到,当url是根级目录的时候,则指向了一个组件,这个组件放在pages文件下,叫做index.vue ,所以组件是用后缀名为.vue写的。

9.     那么一个组件(也就是一个后缀名为.vue)的内容有哪些呢?通过看下面这个index.vue,我们可以发现,这个组件包含了两部分:template 和style两个标签。类似于html的格式。这就是为什么说vue是一个前端框架的原因了。其实在一个用vue写的前端的程序,一般就包含三种文件,html、vue、js。

注册vue对象,写在main.js文件中,注册其实就是实例化,实例化其实就是定义一些属性值和一些方法。这些属性和方法就是vue语法要学习的重要部分。

而显示的页面其实就是用一个个vue写的组件。这些组件的代码格式类似于html的格式,可以通过标签来实现一些数据的绑定操作。

10.  现在可以大致明白一个组件,其实就是一个页面,而页面里可以还有页面,这就说明组件也具有父组件和子组件的区别,在父组件中的template中可以使用一个标签将子组件放到父组件的某个位置。这里又要理解一点,标签就类似于一个对象,所以使用一个名字为父组件的名字,就可以将该父组件调用过来了,类似于导入对象,当然这个对象要在父组件中要到,自然就要在该父组件中使用import来导入子组件。同时在该组件的script中实例化这个子组件。

这就又可以进一步理解,script标签的作用了。上面这个截图我们可以看到script标签为该组件的展示定义了一些样式。

而下面这个截图 就为我们可以看到script标签为这个组件定义了一些属性和方法。

综上我们可以理解script标签就是定义该组件(页面)的一些属性和一些方法的。

下面这个截图中我们发现在父组件的template中使用了一个child的标签,该标签后面的message变量就是子组件的一个属性(变量)。将父组件的msg变量的内容赋值给他,这就可以看出,一个标签<>里面可执行的操作,就类似于定义一个函数,可以在该函数里面写一些逻辑操作(方法)。且在这个标签里面的操作对象是该便签(子组件)的对象,可以将当前组件(父组件)的一些变量值赋值给他,这就实现了父组件和子组件的数据绑定。这个程序就实现了在父组件的input标签下输入内容,则在子组件中的message的内容就跟着变化了。这个过程是动态刷新的,动态刷新就是vue的一个重要特性:可以实现数据的传递和显示动态实时更新。

11.  父组件的内容传递给子组件,只需要在template中的引用子组件标签中,将子组件的变量赋值成父组件要传递给他的变量就ok,因为父组件是先更新变量值的,一旦更新,前面说过组件会定时自动刷新,一属性,子组件的标签就会重新加载一次,这样就把值传过去了(是否通过刷新来实现动态传递的问题还不清楚,后续再论证。)

<inputtype="text" v-model="msg" >  //父组件中将输入值实时绑定到msg中

    <Child:message="msg"></Child> //msg一有变动,子组件的message就获得更新

12.  子组件的内容要传递给父组件,可以通过一个emit来传递。

先在子组件中:定义了一个button按钮,这个按钮通过click点击事件来触发该组件中定义的一个方法send(可以把send理解成一个函数,即通过该按钮的点击事件来调用这个函数)(这里我们发现@click这样的表示,前面有@ 说明这是一个特殊的对象,(面向对象的知识告诉我们,一切皆对象,包括我们定义的所有变量或者方法都可以看做是对象,那么加了@说明是vue内部定义的对象,特殊对象,他有特殊的功能,就是当把这个对象放在button标签(button便签也是一个对象)的里面的时候,就说明,将该button对象实例了一个click的对象,那么button就拥有了这个对象作为自己的属性了。而这个对象的作用就是当用户点击这个button的时候,可以让程序去执行某个事情,在这里就是去执行send方法。))

在子组件里的script中可以看到定义了一个send方法,这个方法就一条语句,这个语句就是调用该组件(this)的一个方法emit,这个方法可以将第二个参数传递给第一个参数,那么emitMessage是什么呢?这可以理解当这个emit方法在编译的时候,这个emitMessage参数就被设定成为了一个全局的变量。在其他任意一个组件中都可以使用这个变量。而这个变量的值,只会在这个子组件中的那个按钮被点击的时候,才会将子组件的一个变量message的值传给他。这个参数的名字是可以任意的。

接下来就好理解父组件如何得到子组件传来的值了,其实就是通过全局变量的emitMessage这个变量来获取。它就相当于一个桥梁。我们可以看到父组件定义了一个emitData的变量来接收这个emitMessage。当父组件引用子组件的时候,就让子组件中使用到的emitMessage这个变量的值等于receiveFun。

而receiveFun其实是一个在父组件定义的方法。这个方法的功能就是要将这个emitMessage的值赋值给自己的变量emitData。我们发现这个方法是带参数的,即message,其实这个message就是子组件的message。他就是通过emit方法传给emitMessage,然后带给父组件的。


13.  $on 监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。Function的参数就来自于bus这个实例(组件)定义的enent-name事件,这个事件会有一个参数输出,输出的这个参数就赋值给了functionmsg参数,然后这个回调函数做的事就是将这个msg赋值给当前组件的show变量,这就实现了接收另外一个组件的信息,实现了组件之间的通信。

 

下面要看一下bus组件到底定义了什么事件,这个事件输出的是什么信息。其实我们已经猜到,这个组件就是待传出信息的那个组件,他将他的信息用emit来传出来。(这里的bus并不是待传出信息的那个组件,而是接受组件和传出组件的根组件。)

14.  Vue中有专门的组件来处理数据存储: Vuex。












原创粉丝点击