第三节 前后端分离开发
1、介绍
开发模式
-
前后端混合开发:传统开发模式
-
前后端分离开发:当前最为主流的开发模式
-
页面原型+需求案例:分析出接口文档
-
离线开发文档示例:
2、YAPI(官网已停用)
2023.7停止维护了,已经登录不上官网了。
在线接口文档管理平台:
- 介绍:YApi 是高效、易用、功能强大的 api 管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务
- 地址:
http://yapi.smart-xwork.cn/
- 2个功能:
- API接口管理
- Mock服务:通过YAPI平台模拟真实接口,生成接口的模拟测试数据,用于前端工程测试。这样即使后端的人员没有开发完毕,前端开发人员也可以使用YAPI平台所提供的Mock地址来进行模拟数据的测试。
使用:
- 可以部署在公司内部服务器,公司内部自己使用。也可以使用YAPI官方提供的公网部署的YAPI平台,注册一个账号使用。
2.1、添加项目
- 步骤:
2.2、添加分类
- 步骤:
2.3、添加接口
- 步骤:
2.4、编辑接口详细信息
- 步骤:
2.5、预览效果
- 接口文档保存后,会自动生成一个Mock地址
- 点击此地址可以看到会自动的生成Mock测试数据:前端人员在测试的时候就可以直接访问此地址进行测试。
- 这个数据是根据定义接口时,指定的返回数据格式生成的
2.6、高级Mock
- 当然这个返回数据里面的值是个比较宽泛的数据,可以在高级Mock功能中,手动指定当前接口生成的测试数据是什么。
修改value中的值:
再次点击预览中的MocK地址,可以看到生成的测试数据已经被改变了。
第四节 前端工程化
1、说明
-
当前开发中使用到的前端资源,我们什么时候使用就什么时候引用。
- 最终形成的工程结构如下:
- 缺点:在大型项目开发中会存在很多问题,每一次开发一个功能都是从0开始,多个页面当中的组件或者是功能复用性并不好,并且js文件、图片文件没有规范化的存储目录,想怎么定义就怎么定义,团队协作开发时每个开发人员都有自己的开发习惯,这样就很不方便项目的维护以及管理。
- 最终形成的工程结构如下:
-
现在的前端开发都讲究前端开发的模块化、组件化、规范化、自动化:
-
模块化:把js、css制作成一个个可以复用的模块
-
组件化:把UI组件,css样式,js行为封装为一个个的组件,便于管理。
-
规范化:提供一套标准规范的目录结构和编码规范,所有开发人员都遵循这一套统一的规范进行开发。
-
自动化:项目的构建、项目的部署、项目的测试都可以自动化的完成。
-
问题
:使用前端工程化以后,在使用vue开发大型项目的时候,我们就需要考虑代码的目录结构,项目的目录结构,部署,以及代码的单元测试等事情。如果每一个项目都手动的完成这些工作那么效率是非常低下的。- 所以通常会使用一些现成的工具来帮助我们完成这些事情,这个工具就是vue官方提供的脚手架工具。
-
2、Vue脚手架的环境准备
- 介绍:Vue-cli 是Vue官方提供的一个脚手架,用于快速生成一个Vue的项目模板。
心 - Vue-cli提供了如下功能:
- 统一的目录结构
- 本地调试
- 热部署
- 单元测试
- 集成打包上线
- 依赖环境:Node]s(类似于java当中的jdk)
2.1、安装NodeJS
-
官网:https://nodejs.org/en
-
安装步骤:
-
双击资料中提供的安装包
-
选择安装目录:选择安装到一个,没有中文,没有空格的目录下(新建一个文件夹NodeJS)
-
验证NodeJS环境变量:
NodeJS 安装完毕后,会自动配置好环境变量,我们验证一下是否安装成功,通过:node -v
-
配置npm的全局安装路径
使用管理员身份运行命令行,在命令行中,执行如下指令:
npm config set prefix "E:\develop\NodeJS"
注意:E:\develop\NodeJS 这个目录是NodeJS的安装目录 -
切换npm的淘宝镜像:可以加速资源下载
使用管理员身份运行命令行,在命令行中,执行如下指令:
npm config set registry https://registry.npm.taobao.org
-
安装Vue-cli
使用管理员身份运行命令行,在命令行中,执行如下指令:
npm install -g @vue/cli
这个过程中,会联网下载,可能会耗时几分钟,耐心等待。
-
查看Vue-cli是否安装成功:
vue --version
-
3、Vue项目简介
3.1、基于脚手架创建Vue项目
- 基于脚手架创建好一个工程化的vue项目
- 方式一:命令行(直接在命令行中输入
vue create 项目名称
)
- 方式二:图形化界面(在命令行中输入命令
vue ui
,回车后就会vue的项目管理器图形化界面,在此界面中再来创建vue项目)
- 方式一:命令行(直接在命令行中输入
- 案例测试:以方式二为例
- 在F盘新创建一个文件夹,以管理员身份打开命令提示符窗口,在窗口中进入到这个新创建的文件夹目录。输入指令
vue ui
,调出图形化界面。
- 可以看到磁盘目录已经创建好vue项目了:
- 在F盘新创建一个文件夹,以管理员身份打开命令提示符窗口,在窗口中进入到这个新创建的文件夹目录。输入指令
3.2、项目目录结构
- 基于Vue脚手架创建出来的工程,有标准的目录结构,如下:
4、使用vscode打开vue项目
- 打开vue项目所在的文件夹
5、运行vue项目
- 2种方式:
- 图形化界面
- 命令行
- 说明:图形化界面方式需要使用npm脚本运行vue项目,所以要先打开npm脚本工具栏。
重启VSCode,点开项目中的package.json,在资源管理器右边的...
中勾选npm脚本,就可以在左下看到NPM脚本
- 以图形化界面方式为例,运行当前案例的vue项目:
- 以管理员方式打开vscode,之后使用npm运行
- vue项目构建完毕后它会自动启动一个服务,运行在8080端口号上,所以可以通过此链接访问当前项目。
- 这个页面是vue项目中自动提供的根组件App.vue,这个组件指的就是一个页面。
- 修改页面的文本:Home—>Vue Home,之后ctrl+s保存,发现没有重启项目,也没有刷新浏览器,页面仍然发生了变化,这就是vue项目提供的热部署功能。
6、修改前端vue项目的端口号
- 在vue的配置文件vue.config.js中进行修改,ctrl+s进行保存。
- 由于修改了端口号,所以在终端中停掉当前的服务,之后重新启动。
7、Vue项目开发流程
说明:
- 启动工程化的vue项目,访问到的页面其实就是vue项目项目默认提供的首页index.html。
创建好vue项目之后,public这个目录下自带的一个页面index.html
开发流程:
- 在index.html首页中(public目录下)它是默认引入了入口文件main.js(此文件是vue项目的入口js文件,在src目录下)
- 在入口文件main.js中又引入了很多的公共组件,import关键字引入模块,export关键字将对象或函数导出为模块。
- 这样就可以通过export关键字来导出一个模块,然后在使用到的地方通过import这个关键字再将其导入进来。
- eg:
import App from './App.vue'
,表示导入当前目录下的App.vue这个组件,并且给它起个名字为App,之后就可以在这个main.js文件中使用这个App组件了。
- 在index.htm只是定义了一个空的div标签,但是界面中展示了很多的信息,那么它是怎么做到的呢???
- 答:在创建vue对象的时候,通过render函数创建了对应的虚拟Dom元素,这部分Dom元素是在App.vue这个根组件中定义的。
- 在vue项目中会看到很多的以.vue为结尾的文件,被叫做组件文件,每个组件文件都由三部分组成。
- 案例测试:改造App.vue组件
<template>
<div >
<!-- 当我们定义好了一个数据模型之后,就可以在上面的模版中
通过插值表达式来展示出数据模型当中的数据
-->
<h1>{{message}}</h1>
</div>
</template>
/* 快捷键:script,选择javascript.vue生成。
export default:表示将定义的这一部分对象导出去,只有在这个地方将它
导出一个模块,在别的地方才可以通过import关键字导入进来。
定义vue当中的数据模型:之前,new一个vue对象,之后声明一个属性data,然后在里面指定一个对象。
现在,不能指定一个对象只能是指定一个函数function,之后在function函数
中声明一个对象,并且要把对象return回去,
*/
<script>
export default {
data() {
return {
message: "Hello vue"
}
},
//如果还想要定义方法,则使用methods属性,在此属性中定义一个个的方法。
methods: {
}
}
</script>
<style>
</style>
- 使用管理员方式打开vscode,并运行,发现数据模型的数据已经被改变了
- 说明:vue项目的开发,其实很少操作main.js入口文件和首页index.heml,主要操作的就是一些组件文件(.vue结尾的文件)。
第五节 Vue组件库Element
1、什么是Element
- Element:是饿了么团队研发的,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
- 组件:组成网页的部件,例如 超链接、按钮、图片、表格、表单、分页条等等。
- 官网:
https://element.eleme.cn/#/zh-CNListener
- 为什么要学Element,通过下图的原始html标签所构建的网页和Element提供的各个的网页组件构建的网页效果对比,可以看出右边的完胜。
2、快速入门
步骤说明:
-
安装ElementUI组件库 (在当前工程的目录下),在命令行执行指令:
-
引入ElementUI组件库
-
访问官网,复制组件代码,调整
案例演示
- 步骤1:安装ElementUI组件库 :
npm install element-ui@2.15.3
,回车后他会联网下载ElementUI的2.15.3版本,并将其安装在当前项目中,会存放在node_modules这个目录下
在node_modules这个目录下,可以看到element-ui目录,说明组件库安装成功。
- 步骤2:在入口文件main.js中,引入ElementUI组件库
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
- 步骤3:定义一个组件文件访问官网,复制组件代码。(根组件只有一个App.vue,其它的组件可以放在views这个目录下,它自带的有2个vue组件。)
- 定义文件夹:element,定义文件:ElementView.vue,在文件中定义基本的结构。
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
- 复制官网的组件代码,之后进行调整
把样式复制到div标签内部:
<div>
<!-- button按钮,如果我们复制的组件比较繁琐,还要往下看一下是否还有一些其它的数据模型
或者vue中方法的定义,如果有也要一并复制过来。 -->
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
</div>
- 运行测试:管理员方式打开vscode并运行,发现显示的结果是之前修改后的根组件首页。因为默认情况下展示的是根组件的内容。
- 修改:在根组件App.vue中,引入ElementView.vue这个组件
- 直接使用
</element-view>
标,此时它会自动在script标签中使用import关键字将这个组件导入进来,并且在vue对象中已经把这个组件加入进来了。
- 再次测试:
3、常用组件
- 学习思路:那对于element当中的常见组件的学习呢,只需要去参照element的官方网站,然后找到对应的组件,查找到组件的源代码,之后复制到vscode的组件中,然后做一些简单地调整即可,把它改成我们想要的样式。
3.1、常见组件-表格
- Table 表格:用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
- 官方网站:以带边框表格为例
可以看到表格还要展示数据模型,所以可以把要展示的数据模型也复制进来。
- 组件代码:复制进来后ctrl+alt+L,页面格式化 更规整的显示。
<!-- Table表格 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
},
- 如果不清楚表格中的属性代表的含义,可以在官网中每一个组件的最下面找到对属性的解释:
- 测试:由于自带的热部署,所以不需要启动项目也不用刷新浏览器
3.2、常见组件-分页
- Pagination 分页:当数据量过多时,使用分页分解数据。
- 官网:
- 组件代码:
<!-- Pagination 分页 -->
<el-pagination background layout="prev, pager, next" :total="1000">
</el-pagination>
- 效果:
- 添加事件:重听
<!-- Pagination 分页 -->
<el-pagination background layout="total,sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="1000"></el-pagination>
methods: {
handleSizeChange:function(val){
alert("每页记录数变化" + val)
},
handleCurrentChange:function(val){
alert("页码发生变化" + val)
},
onSubmit:function(){
alert(JSON.stringify(this.form));
}
}
3.3、常见组件-对话框
-
Dialog 对话框:在保留当前页面状态的情况下,告知用户并承载相关操作。
-
官网:
-
组件代码
<!-- Dialog对话框 -->
<!-- Table -->
<el-button type="text" @click="dialogTableVisible = true">打开嵌套表格的 Dialog</el-button>
<el-dialog title="收货地址" :visible.sync="dialogTableVisible">
<el-table :data="gridData">
<el-table-column property="date" label="日期" width="150"></el-table-column>
<el-table-column property="name" label="姓名" width="200"></el-table-column>
<el-table-column property="address" label="地址" width="200"></el-table-column>
</el-table>
</el-dialog>
gridData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
dialogTableVisible: false
- 效果:
3.4、常见组件-表单
重听
-
Form 表单:由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
-
官网:
-
功能:点击按钮呈现一个表单,要用到上面的Dialog对话框,只不过里面的内容展示的是form表单。
<!-- Dialog对话框-Form表单 -->
<el-button type="text" @click="dialogFormVisible = true">打开嵌套Form的 Dialog</el-button>
<el-dialog title="Form表单" :visible.sync="dialogFormVisible">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
/* 表单项绑定的数据模型 */
form: {
name: '',
region: '',
date1: '',
date2: ''
},
//声明表单的数据模型
dialogFormVisible: false,
/* 提交按钮的事件 */
onSubmit:function(){
/*提交按钮时拿到表单数据,因为这些表单项的数据都绑定在了form数据模型中,
所以要查看表达项数据直接把form这个对象输出出来就可以了,直接输出的是
对象,需要把它转化为字符串输出才可以看到里面的数据*/
alert(JSON.stringify(this.form));
}
- 效果:
4、案例
4.1、需求分析&开发步骤
- 案例需求:根据页面原型完成员工管理页面开发,并通过Axios完成数据异步加载。
- 服务端数据获取地址:http://yapi.smart-xwork.cn/mock/169327/emp/list
通过在线文档YAPI生成的测试数据。
- 最终实现的页面效果
- 实现步骤:
4.2、基本页面布局
- 添加组件,在组件中编写基本结构
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
-
修改根组件的引入方式
-
编写页面布局:这个页面布局不需要自己编写,在Element中还提供了一个布局组件(Container 布局容器)
-
可以选择一个常见的页面布局,符合当前案例的开发页面的
-
效果:
-
添加css样式
<template>
<div>
<el-container style="height: 700px; border: 1px solid #eee">
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
>tlias 智能学习辅助系统</el-header
>
<el-container>
<el-aside width="200px">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>系统信息管理</template>
<el-menu-item index="1-1">部门管理</el-menu-item>
<el-menu-item index="1-2">员工管理</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<el-table :data="tableData">
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="image" label="图像" width="180"></el-table-column>
<el-table-column prop="gender" label="性别" width="140"></el-table-column>
<el-table-column prop="job" label="职位" width="140"></el-table-column>
<el-table-column prop="entrydate" label="入职日期" width="180"></el-table-column>
<el-table-column prop="updatetime" label="最后操作时间" width="230"></el-table-column>
<el-table-column label="操作" >
<el-button type="primary" size="mini">编辑</el-button>
<el-button type="danger" size="mini">删除</el-button>
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
data() {
return {
tableData: []
}
},
};
</script>
<style>
</style>
- 最终效果:
4.3、页面组件实现
- 效果
4.4、axios异步加载数据
Vue项目中使用Axios:
- 在项目目录下安装axios:
npm install axios
; - 需要使用axios时,导入axios:
import axios from 'axios'
;
案例测试:
- 打开集成终端,输入命令进行安装
- 导入axios,在钩子函数中编写axios发送请求
<template>
<div>
<el-container style="height: 700px; border: 1px solid #eee">
<el-header style="font-size:40px; background-color: rgb(238, 241, 246)">tlias 智能学习辅助系统</el-header>
<el-container>
<el-aside width="230px" style="border: 1px solid #eee">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>系统信息管理</template>
<el-menu-item index="1-1">部门管理</el-menu-item>
<el-menu-item index="1-2">员工管理</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<!-- 表单 -->
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="姓名">
<el-input v-model="searchForm.name" placeholder="姓名"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="searchForm.gender" placeholder="性别">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="入职日期">
<!-- 日期选择器 -->
<el-date-picker
v-model="searchForm.entrydate"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<!-- 表格 -->
<el-table :data="tableData" border>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column label="图像" width="180">
<template slot-scope="scope">
<img :src="scope.row.image" width="100px" height="70px">
</template>
</el-table-column>
<el-table-column label="性别" width="140">
<template slot-scope="scope">
{{scope.row.gender == 1 ? '男':'女'}}
</template>
</el-table-column>
<el-table-column prop="job" label="职位" width="140"></el-table-column>
<el-table-column prop="entrydate" label="入职日期" width="180"></el-table-column>
<el-table-column prop="updatetime" label="最后操作时间" width="230"></el-table-column>
<el-table-column label="操作" >
<el-button type="primary" size="mini">编辑</el-button>
<el-button type="danger" size="mini">删除</el-button>
</el-table-column>
</el-table>
<br>
<!-- 分页条 -->
<!-- Pagination 分页 -->
<el-pagination background layout="total,sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:total="1000"></el-pagination>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tableData: [],
searchForm: {
name:"",
gender:"",
entrydate:[]
}
}
},
methods: {
onSubmit:function(){
alert("查询数据");
},
handleSizeChange:function(val){
alert("每页记录数变化" + val)
},
handleCurrentChange:function(val){
alert("页码发生变化" + val)
}
},
mounted () {
//发送异步请求,获取数据
axios.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then((result) => {
this.tableData = result.data.data;
});
}
}
</script>
<style>
</style>
- 效果
5、Vue路由
6、打包部署
6.1、说明
- 前后端分离开发模式中,前端人员开发前端工程,后端人员开发后端工程,最终将前端工程和后端工程分开部署在对应的服务器上,而前端服务器当前最流行的就是nginx。
6.2、步骤-打包
- 打包:打包后会将项目放在dist这个目录下
- 案例测试:
打开dist所在的磁盘目录
打包后的文件
6.3、步骤-部署
说明:
- 将dist这个目录下打包后的这些资源呢部署在服务器上就可以了
- nginx服务器介绍:
- 介绍:Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,在各大型互联网公司都有非常广泛的使用。
- 官网:
https://nginx.org/
案例测试:
-
下载解压nginx稳定版到一个没有中文的目录
-
部署:将打包好的 dist 目录下的文件,复制到nginx安装目录的html目录下。
- 有2个默认的页面可以删除掉
- 有2个默认的页面可以删除掉
-
启动:双击 nginx.exe 文件即可,Nginx服务器默认占用 80 端口号
- 启动:
- 注意事项:Nginx默认占用80端口号,如果80端口号被占用,可以在nginx.conf中修改端口号。(
netstat –ano | findStr 80
)
比如修改为90,之后重启nginx。
- 访问测试:
注意:这里只是演示的是nginx部署静态资源,它本身还可以反向代理,负载均衡等功能。
- 启动: