1 Ajax
1.1 Ajax介绍
1.1.1 Ajax概述
我们前端页面中的数据,如下图所示的表格中的学生信息,应该来自于后台,那么我们的后台和前端是互不影响的2个程序,那么我们前端应该如何从后台获取数据呢?因为是2个程序,所以必须涉及到2个程序的交互,所以这就需要用到我们接下来学习的Ajax技术。
Ajax: 全称Asynchronous JavaScript And XML,异步的JavaScript和XML。其作用有如下2点:
- 与服务器进行数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等。
1.1.2 Ajax作用
我们详细的解释一下Ajax技术的2个作用
-
与服务器进行数据交互
如下图所示前端资源被浏览器解析,但是前端页面上缺少数据,前端可以通过Ajax技术,向后台服务器发起请求,后台服务器接受到前端的请求,从数据库中获取前端需要的资源,然后响应给前端,前端在通过我们学习的vue技术,可以将数据展示到页面上,这样用户就能看到完整的页面了。此处可以对比JavaSE中的网络编程技术来理解。
-
异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。
如下图所示,当我们再百度搜索java时,下面的联想数据是通过Ajax请求从后台服务器得到的,在整个过程中,我们的Ajax请求不会导致整个百度页面的重新加载,并且只针对搜索栏这局部模块的数据进行了数据的更新,不会对整个页面的其他地方进行数据的更新,这样就大大提升了页面的加载速度,用户体验高。
1.1.3 同步异步
针对于上述Ajax的局部刷新功能是因为Ajax请求是异步的,与之对应的有同步请求。接下来我们介绍一下异步请求和同步请求的区别。
- 同步请求发送过程如下图所示:
浏览器页面在发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他的操作。只能等到服务器响应结束后才能,浏览器页面才能继续做其他的操作。 - 异步请求发送过程如下图所示:
浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作。
1.2 原生Ajax
对于Ajax技术有了充分的认知了,我们接下来通过代码来演示Ajax的效果。此处我们先采用原生的Ajax代码来演示。因为Ajax请求是基于客户端发送请求,服务器响应数据的技术。所以为了完成快速入门案例,我们需要提供服服务器端和编写客户端。
-
服务器端
因为我们暂时还没学过服务器端的代码,所以此处已经直接提供好了服务器端的请求地址,我们前端直接通过Ajax请求访问该地址即可。后台服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/list
上述地址我们也可以直接通过浏览器来访问,访问结果如图所示:只截取部分数据
-
客户端
客户端的Ajax请求代码如下有如下4步,接下来我们跟着步骤一起操作一下。
第一步:首先我们再VS Code中创建AJAX的文件夹,并且创建名为01. Ajax-原生方式.html的文件,提供如下代码,主要是按钮绑定单击事件,我们希望点击按钮,来发送ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生Ajax</title>
</head>
<body>
<input type="button" value="获取数据" onclick="getData()">
<div id="div1"></div>
</body>
<script>
function getData(){
}
</script>
</html>
第二步:创建XMLHttpRequest对象,用于和服务器交换数据,也是原生Ajax请求的核心对象,提供了各种方法。代码如下:
//1. 创建XMLHttpRequest
var xmlHttpRequest = new XMLHttpRequest();
第三步:调用对象的open()方法设置请求的参数信息,例如请求地址,请求方式。然后调用send()方法向服务器发送请求,代码如下:
//2. 发送异步请求
xmlHttpRequest.open('GET','http://yapi.smart-xwork.cn/mock/169327/emp/list');
xmlHttpRequest.send();//发送请求
第四步:我们通过绑定事件的方式,来获取服务器响应的数据。
//3. 获取服务响应数据
xmlHttpRequest.onreadystatechange = function(){
//此处判断 4表示浏览器已经完全接受到Ajax请求得到的响应, 200表示这是一个正确的Http请求,没有错误
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
document.getElementById('div1').innerHTML = xmlHttpRequest.responseText;
}
}
最后我们通过浏览器打开页面,请求点击按钮,发送Ajax请求,最终显示结果如下图所示:
1.3 Axios
上述原生的Ajax请求的代码编写起来还是比较繁琐的,所以接下来我们学习一门更加简单的发送Ajax请求的技术Axios 。Axios是对原生的AJAX进行封装,简化书写。Axios官网是:https://www.axios-http.cn
1.3.1 Axios的基本使用
Axios的使用比较简单,主要分为2步:
-
引入Axios文件
<script src="js/axios-0.18.0.js"></script>
-
使用Axios发送请求,并获取响应结果,官方提供的api很多,此处给出2种,如下
-
发送 get 请求
axios({ method:"get", url:"http://localhost:8080/ajax-demo1/aJAXDemo1?username=zhangsan" }).then(function (resp){ alert(resp.data); })
-
发送 post 请求
axios({ method:"post", url:"http://localhost:8080/ajax-demo1/aJAXDemo1", data:"username=zhangsan" }).then(function (resp){ alert(resp.data); });
axios()是用来发送异步请求的,小括号中使用 js的JSON对象传递请求相关的参数:
- method属性:用来设置请求方式的。取值为 get 或者 post。
- url属性:用来书写请求的资源路径。如果是 get 请求,需要将请求参数拼接到路径的后面,格式为: url?参数名=参数值&参数名2=参数值2。
- data属性:作为请求体被发送的数据。也就是说如果是 post 请求的话,数据需要作为 data 属性的值。
then() 需要传递一个匿名函数。我们将 then()中传递的匿名函数称为 回调函数,意思是该匿名函数在发送请求时不会被调用,而是在成功响应后调用的函数。而该回调函数中的 resp 参数是对响应的数据进行封装的对象,通过 resp.data 可以获取到响应的数据。
-
1.3.2 Axios快速入门
-
后端实现
查询所有员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/list
根据员工id删除员工信息服务器地址:http://yapi.smart-xwork.cn/mock/169327/emp/deleteById
-
前端实现
首先在VS Code中创建js文件夹,与html同级,然后将资料/axios-0.18.0.js 文件拷贝到js目录下,然后创建名为02. Ajax-Axios.html的文件,工程结果如图所示:
然后在html中引入axios所依赖的js文件,并且提供2个按钮,绑定单击事件,分别用于点击时发送ajax请求,完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax-Axios</title>
<script src="js/axios-0.18.0.js"></script>
</head>
<body>
<input type="button" value="获取数据GET" onclick="get()">
<input type="button" value="删除数据POST" onclick="post()">
</body>
<script>
function get(){
//通过axios发送异步请求-get
}
function post(){
//通过axios发送异步请求-post
}
</script>
</html>
然后分别使用Axios的方法,完整get请求和post请求的发送
get请求代码如下:
//通过axios发送异步请求-get
axios({
method: "get",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/list"
}).then(result => {
console.log(result.data);
})
post请求代码如下:
//通过axios发送异步请求-post
axios({
method: "post",
url: "http://yapi.smart-xwork.cn/mock/169327/emp/deleteById",
data: "id=1"
}).then(result => {
console.log(result.data);
})
浏览器打开,f12抓包,然后分别点击2个按钮,查看控制台效果如下:
-
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ajax-Axios</title> <script src="js/axios-0.18.0.js"></script> </head> <body> <input type="button" value="获取数据GET" onclick="get()"> <input type="button" value="删除数据POST" onclick="post()"> </body> <script> function get(){ //通过axios发送异步请求-get axios({ method: "get", url: "http://yapi.smart-xwork.cn/mock/169327/emp/list" }).then(result => { console.log(result.data); }) } function post(){ // 通过axios发送异步请求-post axios({ method: "post", url: "http://yapi.smart-xwork.cn/mock/169327/emp/deleteById", data: "id=1" }).then(result => { console.log(result.data); }) } </script> </html>
1.3.3 请求方法的别名
Axios还针对不同的请求,提供了别名方式的api,具体如下:
方法 | 描述 |
---|---|
axios.get(url [, config]) | 发送get请求 |
axios.delete(url [, config]) | 发送delete请求 |
axios.post(url [, data[, config]]) | 发送post请求 |
axios.put(url [, data[, config]]) | 发送put请求 |
我们目前只关注get和post请求,所以在上述的入门案例中,我们可以将get请求代码改写成如下:
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
console.log(result.data);
})
post请求改写成如下:
axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(result => {
console.log(result.data);
})
1.3.4 案例
-
需求:基于Vue及Axios完成数据的动态加载展示,如下图所示
其中数据是来自于后台程序的,地址是:http://yapi.smart-xwork.cn/mock/169327/emp/list -
分析:
前端首先是一张表格,我们缺少数据,而提供数据的地址已经有了,所以意味这我们需要使用Ajax请求获取后台的数据。但是Ajax请求什么时候发送呢?页面的数据应该是页面加载完成,自动发送请求,展示数据,所以我们需要借助vue的mounted钩子函数。那么拿到数据了,我们该怎么将数据显示表格中呢?这里就得借助v-for指令来遍历数据,展示数据。
-
步骤:
- 首先创建文件,提前准备基础代码,包括表格以及vue.js和axios.js文件的引入
- 我们需要在vue的mounted钩子函数中发送ajax请求,获取数据
- 拿到数据,数据需要绑定给vue的data属性
- 在<tr>标签上通过v-for指令遍历数据,展示数据
-
代码实现:
- 首先创建文件,提前准备基础代码,包括表格以及vue.js和axios.js文件的引入
- 首先创建文件,提前准备基础代码,包括表格以及vue.js和axios.js文件的引入
-
提供初始代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ajax-Axios-案例</title> <script src="js/axios-0.18.0.js"></script> <script src="js/vue.js"></script> </head> <body> <div id="app"> <table border="1" cellspacing="0" width="60%"> <tr> <th>编号</th> <th>姓名</th> <th>图像</th> <th>性别</th> <th>职位</th> <th>入职日期</th> <th>最后操作时间</th> </tr> <tr align="center" > <td>1</td> <td>Tom</td> <td> <img src="" width="70px" height="50px"> </td> <td> <span>男</span> <!-- <span>女</span>--> </td> <td>班主任</td> <td>2009-08-09</td> <td>2009-08-09 12:00:00</td> </tr> </table> </div> </body> <script> new Vue({ el: "#app", data: { } }); </script> </html>
-
在vue的mounted钩子函数,编写Ajax请求,请求数据,代码如下:
mounted () { //发送异步请求,加载数据 axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => { }) }
-
ajax请求的数据我们应该绑定给vue的data属性,之后才能进行数据绑定到视图;并且浏览器打开后台地址,数据返回格式如下图所示:
-
-
因为服务器响应的json中的data属性才是我们需要展示的信息,所以我们应该将员工列表信息赋值给vue的data属性,代码如下:
//发送异步请求,加载数据 axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => { this.emps = result.data.data; })
其中,data中生命emps变量,代码如下:
data: { emps:[] },
-
在<tr>标签上通过v-for指令遍历数据,展示数据,其中需要注意的是图片的值,需要使用vue的属性绑定,男女的展示需要使用条件判断,其代码如下:
<tr align="center" v-for="(emp,index) in emps"> <td>{{index + 1}}</td> <td>{{emp.name}}</td> <td> <img :src="emp.image" width="70px" height="50px"> </td> <td> <span v-if="emp.gender == 1">男</span> <span v-if="emp.gender == 2">女</span> </td> <td>{{emp.job}}</td> <td>{{emp.entrydate}}</td> <td>{{emp.updatetime}}</td> </tr>
-
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax-Axios-案例</title>
<script src="js/axios-0.18.0.js"></script>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<table border="1" cellspacing="0" width="60%">
<tr>
<th>编号</th>
<th>姓名</th>
<th>图像</th>
<th>性别</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
</tr>
<tr align="center" v-for="(emp,index) in emps">
<td>{{index + 1}}</td>
<td>{{emp.name}}</td>
<td>
<img :src="emp.image" width="70px" height="50px">
</td>
<td>
<span v-if="emp.gender == 1">男</span>
<span v-if="emp.gender == 2">女</span>
</td>
<td>{{emp.job}}</td>
<td>{{emp.entrydate}}</td>
<td>{{emp.updatetime}}</td>
</tr>
</table>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
emps:[]
},
mounted () {
//发送异步请求,加载数据
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
console.log(result.data);
this.emps = result.data.data;
})
}
});
</script>
</html>
2 前后台分离开发
2.1 前后台分离开发介绍
在之前的课程中,我们介绍过,前端开发有2种方式:前后台混合开发和前后台分离开发。
前后台混合开发,顾名思义就是前台后台代码混在一起开发,如下图所示:
这种开发模式有如下缺点:
- 沟通成本高:后台人员发现前端有问题,需要找前端人员修改,前端修改成功,再交给后台人员使用
- 分工不明确:后台开发人员需要开发后台代码,也需要开发部分前端代码。很难培养专业人才
- 不便管理:所有的代码都在一个工程中
- 不便维护和扩展:前端代码更新,和后台无关,但是需要整个工程包括后台一起重新打包部署。
所以我们目前基本都是采用的前后台分离开发方式,如下图所示:
我们将原先的工程分为前端工程和后端工程这2个工程,然后前端工程交给专业的前端人员开发,后端工程交给专业的后端人员开发。前端页面需要数据,可以通过发送异步请求,从后台工程获取。但是,我们前后台是分开来开发的,那么前端人员怎么知道后台返回数据的格式呢?后端人员开发,怎么知道前端人员需要的数据格式呢?所以针对这个问题,我们前后台统一指定一套规范!我们前后台开发人员都需要遵循这套规范开发,这就是我们的接口文档。接口文档有离线版和在线版本,接口文档示可以查询今天提供资料/接口文档示例里面的资料。那么接口文档的内容怎么来的呢?是我们后台开发者根据产品经理提供的产品原型和需求文档所撰写出来的,产品原型示例可以参考今天提供资料/页面原型里面的资料。
那么基于前后台分离开发的模式下,我们后台开发者开发一个功能的具体流程如何呢?如下图所示:
- 需求分析:首先我们需要阅读需求文档,分析需求,理解需求。
- 接口定义:查询接口文档中关于需求的接口的定义,包括地址,参数,响应数据类型等等
- 前后台并行开发:各自按照接口文档进行开发,实现需求
- 测试:前后台开发完了,各自按照接口文档进行测试
- 前后段联调测试:前段工程请求后端工程,测试功能
2.2 YAPI
2.2.1 YAPI介绍
前后台分离开发中,我们前后台开发人员都需要遵循接口文档,所以接下来我们介绍一款撰写接口文档的平台。
YApi 是高效、易用、功能强大的 api 管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。
其官网地址:http://yapi.smart-xwork.cn/
YApi主要提供了2个功能:
- API接口管理:根据需求撰写接口,包括接口的地址,参数,响应等等信息。
- Mock服务:模拟真实接口,生成接口的模拟测试数据,用于前端的测试。
2.2.2 接口文档管理
接下来我们演示一下YApi是如何管理接口文档的。
首先我们登录YAPI的官网,然后使用github或者百度账号登录,没有的话去注册一个,如下图所示:
登录进去后,在个人空间中,选择项目列表->添加测试项目,效果如图所示:
然后点击创建的项目,进入到项目中,紧接着先添加接口的分类,如下图所示
然后我们选择当前创建的分类,创建接口信息,如下图所示:
紧接着,我们来到接口的编辑界面,对接口做生层次的定制,例如:接口的参数,接口的返回值等等,效果图下图所示:
添加接口的请求参数,如下图所示:
添加接口的返回值,如下图所示:
然后保存上述设置,紧接着我们可以来到接口的预览界面,查询接口的信息,其效果如下图所示:篇幅有限,只截取部分
最后,我们还可以设置接口的mock信息,
来到接口的Mock设置窗口,如下图所示:
紧接着我们来到接口的预览界面,直接点击Mock地址,如下图所示:
我们发现浏览器直接打开,并返回如下数据:
如上步骤就是YAPI接口平台中对于接口的配置步骤。
3 前端工程化
3.1 前端工程化介绍
我们目前的前端开发中,当我们需要使用一些资源时,例如:vue.js,和axios.js文件,都是直接再工程中导入的,如下图所示:
但是上述开发模式存在如下问题:
- 每次开发都是从零开始,比较麻烦
- 多个页面中的组件共用性不好
- js、图片等资源没有规范化的存储目录,没有统一的标准,不方便维护
所以现在企业开发中更加讲究前端工程化方式的开发,主要包括如下4个特点
- 模块化:将js和css等,做成一个个可复用模块
- 组件化:我们将UI组件,css样式,js行为封装成一个个的组件,便于管理
- 规范化:我们提供一套标准的规范的目录接口和编码规范,所有开发人员遵循这套规范
- 自动化:项目的构建,测试,部署全部都是自动完成
所以对于前端工程化,说白了,就是在企业级的前端项目开发中,把前端开发所需要的工具、技术、流程、经验进行规范化和标准化。从而提升开发效率,降低开发难度等等。接下来我们就需要学习vue的官方提供的脚手架帮我们完成前端的工程化。
3.2 前端工程化入门
3.2.1 环境准备
我们的前端工程化是通过vue官方提供的脚手架Vue-cli来完成的,用于快速的生成一个Vue的项目模板。Vue-cli主要提供了如下功能:
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
我们需要运行Vue-cli,需要依赖NodeJS,NodeJS是前端工程化依赖的环境。所以我们需要先安装NodeJS,然后才能安装Vue-cli
-
NodeJS安装和Vue-cli安装
详细安装步骤,请参考资料/NodeJS安装文档/NodeJS安装文档.md文件
3.2.2 Vue项目简介
环境准备好了,接下来我们需要通过Vue-cli创建一个vue项目,然后再学习一下vue项目的目录结构。Vue-cli提供了如下2种方式创建vue项目:
-
命令行:直接通过命令行方式创建vue项目
vue create vue-project01
-
图形化界面:通过命令先进入到图形化界面,然后再进行vue工程的创建
vue ui
图形化界面如下:
然后我门选择创建按钮,在vue文件夹下创建项目,如下图所示:
然后来到如下界面,进行vue项目的创建
然后预设模板选择手动,如下图所示:
然后再功能页面开启路由功能,如下图所示:
然后再配置页面选择语言版本和语法检查规范,如下图所示:
然后创建项目,进入如下界面:
最后我们只需要等待片刻,即可进入到创建创建成功的界面,如下图所示:
到此,vue项目创建结束
3.2.2.2 vue项目目录结构介绍
我们通过VS Code打开之前创建的vue文件夹,打开之后,呈现如下图所示页面:
vue项目的标准目录结构以及目录对应的解释如下图所示:
其中我们平时开发代码就是在src目录下
3.2.2.3 运行vue项目
那么vue项目开发好了,我们应该怎么运行vue项目呢?主要提供了2种方式
- 第一种方式:通过VS Code提供的图形化界面 ,如下图所示:(注意:NPM脚本窗口默认不显示,可以参考本节的最后调试出来)