黑马JavaWeb学习笔记一
Web
浏览器可以访问的网站
访问过程
打开界面后首先展示前端应用程序;接着前端应用程序向服务端提交Java应用程序的请求;最后服务端应用程序将数据提交至数据库系统。
数据库回应服务端程序,服务端程序回应前端程序,前端程序回应浏览器

- 网页由哪几部分组成?
- 文字、图片、视频、音频、超链接…
- 我们看到的网页,背后本质是什么?
- 通过浏览器转换成用户看到的网页。
- 程序员写的前端代码 - 前端代码如何转换成用户眼中的网页?
- 浏览器对代码进行解析渲染的部分,称为浏览器内核
注意:不同浏览器内核其对代码的解析渲染是不一样的
所以我们就需要对代码渲染制定一个规则
Web标准
也被认为是互联网标准,并被称为网页标准;它包含了一系列标准;其中大部分是由W3C(World Wide Web Consortium, 万维网联盟)负责制定的。
三个组成部分:
- HTML:负责网页的结构(页面元素和内容)。
- CSS:负责网页的表现(页面元素的外观、位置等页面样式,如:颜色、大小等)。
- JavaScript:负责网页的行为(交互效果)
什么是HTML

标签有单标签和多标签
图中img就是单标签,h1就是多标签
这些都是指定好的
这些标签是由浏览器解析随后就能再浏览器上面呈现出来的
CSS
用来修饰样式的
具体可以在百度里面搜索MDN进行查看
The MDN Web Docs website offers information on Open Web technologies, such as HTML, CSS, and APIs, which cater to both traditional websites and progressive web applications.

HTML Getting Started

2.Vscode安装
黑马程序员官方文档
[Docs

输入!就可以将前端的基本框架输出出来
在安装过程中需要依次安装15个插件组件,并随后完成第一个实例——HTML快速入门的基本操作流程
<html>
<head>
<title>HTML快速入门</title>
</head>
<body>
<h1>Hello HTML</h1>
<img src="img/1.png">
</body>
</html>
html
<!-- 告诉浏览器当前文档类型为HTML -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 字符集 -->
<meta charset="UTF-8">
<!-- 不同设备屏幕宽度的适配方式 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML快速入门</title>
</head>
<body>
<h1>Hello HTML</h1>
<img src="img/1.png">
<!-- 以下是我使用提示来使用通义灵吗来写代码的一个案例 -->
<!-- 使用一级标签来输出Hello HTML -->
<h1>Hello HTML</h1>
</body>
</html>
html

黑马程序员第五集(感觉没有必要看)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>【新思想引领新征程】推进长江十年禁渔 谱写长江大保护新篇章</title>
</head>
<body>
<!-- 定义一个标题, 标题内容: 【新思想引领新征程】推进长江十年禁渔 谱写长江大保护新篇章 -->
<h1>【新思想引领新征程】推进长江十年禁渔 谱写长江大保护新篇章</h1>
<!-- 定义一个超链接, 里面展示 央视网 -->
<!-- a 超链接标签:
href: 链接地址 - url地址
target: 打开方式
_blank: 新窗口打开
_self: 本窗口打开(默认)
-->
<a href="https://www.cctv.com" target="_blank">央视网</a>
2024年05月15日 20:07
</body>
</html>
html

这里我是直接跳转到25级Vue的快速入门
Vue
Vue的快速入门

以上是构建用户界面的解释:基于数据渲染出用户可以看得到的网页

此处是对Vue框架层次化理解的一种表述方式,在Vue的发展过程中遵循着逐层扩展的原则,在核心组件的基础上可以通过单独实现某个功能来扩展其功能集,并且也可以通过利用Vue提供的生态系统来构建更复杂的系统架构

以上是对Vue框架的解释


实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-快速入门</title>
</head>
<body>
<div id="app">
<h1>{{message}}</h1>
<h1>{{count}}</h1>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
createApp({
data() {
return {
message: 'Hello Vue',
count: 100
}
}
}).mount('#app');
</script>
</body>
</html>
html

截图

Vue的常见指令

V-for使用

这里是Vue定义的数组,为v-for案例创建一个数组
createApp({
data() {
return {
//empList中[]表示数组,{}表示对象
empList: [
{ "id": 1,
"name": "谢逊",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/4.jpg",
"gender": 1,
"job": "1",
"entrydate": "2023-06-09",
"updatetime": "2024-09-30T14:59:38"
},
{
"id": 2,
"name": "韦一笑",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg",
"gender": 1,
"job": "1",
"entrydate": "2020-05-09",
"updatetime": "2024-09-01T00:00:00"
},
{
"id": 3,
"name": "黛绮丝",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/2.jpg",
"gender": 2,
"job": "2",
"entrydate": "2021-06-01",
"updatetime": "2024-09-01T00:00:00"
}
]
}
},
javascript

v-for使用
<!-- //这里for(元素内容,元素序号)in 数组 -->
<!-- 这里v-for在tr标签中,tr标签只有一个,但是因为v-for的使用就会导致只要数组有多少个元素就会有多少个tr -->
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<!-- 因为gender是数字,所以需要判断一下,如果gender等于1,则返回男,否则返回女 -->
<td>{{e.gender == 1?'男' : '女'}}</td>
html
V-bind使用


<!-- 插值表达式是不能出现在标签内部 -->
<!-- 这里使用了v-bind:因为图片只能使用v-bind:src,这里图片不能使用插值表达式 -->
<!-- alt图像加载失败时的替代显示 这里:alt其实是v-bind:alt 的简写-->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
html
V-if和V-show

<!-- v-if: 控制元素的显示与隐藏 -->
<!-- 这里e是for循环的元素,所以e.job是e这个元素的job属性 -->
<!-- 这里e.job == 1表示如果job等于1,则显示班主任,否则就一个一个下去哪个等于显示哪个 -->
<td>
<span v-if="e.job == 1">班主任</span>
<span v-else-if="e.job == 2">讲师</span>
<span v-else-if="e.job == 3">学工主管</span>
<span v-else-if="e.job == 4">教研主管</span>
<span v-else-if="e.job == 5">咨询师</span>
<span v-else>其他</span>
</td>
<!-- v-show表示元素的显示与隐藏,用处和v-if一样但是其是通过css里面的display:none隐藏 -->
<!-- v-show: 控制元素的显示与隐藏 -->
<!-- <td>
<span v-show="e.job == 1">班主任</span>
<span v-show="e.job == 2">讲师</span>
<span v-show="e.job == 3">学工主管</span>
<span v-show="e.job == 4">教研主管</span>
<span v-show="e.job == 5">咨询师</span>
</td> -->
html

V-model使用

定义一个searchForm
//这里是上面导航栏所搜索的集合
searchForm: { //封装用户输入的查询条件
name: '',
gender: '',
job: ''
},
javascript
<!-- 搜索表单区域 -->
<!-- 这里使用了 v-model 下面定义了一个叫searchForm的对象 -->
<!-- 通过 v-model="searchForm.name"来引出对象,其是一个双向绑定,界面上会显示conlog也会显示 -->
<form class="search-form">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名">
<label for="gender">性别:</label>
<select id="gender" name="gender" v-model="searchForm.gender">
<option value=""></option>
<option value="1">男</option>
<option value="2">女</option>
</select>
<label for="position">职位:</label>
<select id="position" name="position" v-model="searchForm.job">
<option value=""></option>
<option value="1">班主任</option>
<option value="2">讲师</option>
<option value="3">学工主管</option>
<option value="4">教研主管</option>
<option value="5">咨询师</option>
</select>
html

双向数据绑定

V-on使用

<!-- V-on 事件监听器@click 与v-on:click是等价的,都是事件监听器-->
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
html
Tlias智能学习辅助系统案例完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tlias智能学习辅助系统</title>
<style>
/* 导航栏样式 */
.navbar {
background-color: #b5b3b3; /* 灰色背景 */
display: flex; /* flex弹性布局 */
justify-content: space-between; /* 左右对齐 */
padding: 10px; /* 内边距 */
align-items: center; /* 垂直居中 */
}
.navbar h1 {
margin: 0; /* 移除默认的上下外边距 */
font-weight: bold; /* 加粗 */
color: white;
/* 设置字体为楷体 */
font-family: "楷体";
}
.navbar a {
color: white; /* 链接颜色为白色 */
text-decoration: none; /* 移除下划线 */
}
/* 搜索表单样式 */
.search-form {
display: flex;
flex-wrap: nowrap;
align-items: center;
gap: 10px; /* 控件之间的间距 */
margin: 20px 0;
}
.search-form input[type="text"], .search-form select {
padding: 5px; /* 输入框内边距 */
width: 260px; /* 宽度 */
}
.search-form button {
padding: 5px 15px; /* 按钮内边距 */
}
/* 表格样式 */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd; /* 边框 */
padding: 8px; /* 单元格内边距 */
text-align: center; /* 左对齐 */
}
th {
background-color: #f2f2f2;
font-weight: bold;
}
.avatar {
width: 30px;
height: 30px;
}
/* 页脚样式 */
.footer {
background-color: #b5b3b3; /* 灰色背景 */
color: white; /* 白色文字 */
text-align: center; /* 居中文本 */
padding: 10px 0; /* 上下内边距 */
margin-top: 30px;
}
#container {
width: 80%; /* 宽度为80% */
margin: 0 auto; /* 水平居中 */
}
</style>\
</head>
<!-- 以上内容不用看 -->
<body>
<div id="container">
<!-- 顶部导航栏 -->
<div class="navbar">
<h1>Tlias智能学习辅助系统</h1>
<a href="#">退出登录</a>
</div>
<!-- 搜索表单区域 -->
<!-- 这里使用了 v-model 下面定义了一个叫searchForm的对象 -->
<!-- 通过 v-model="searchForm.name"来引出对象,其是一个双向绑定,界面上会显示conlog也会显示 -->
<form class="search-form">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名">
<label for="gender">性别:</label>
<select id="gender" name="gender" v-model="searchForm.gender">
<option value=""></option>
<option value="1">男</option>
<option value="2">女</option>
</select>
<label for="position">职位:</label>
<select id="position" name="position" v-model="searchForm.job">
<option value=""></option>
<option value="1">班主任</option>
<option value="2">讲师</option>
<option value="3">学工主管</option>
<option value="4">教研主管</option>
<option value="5">咨询师</option>
</select>
<!-- V-on 事件监听器@click 与v-on:click是等价的,都是事件监听器-->
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
</form>
<!-- 表格展示区 -->
<table>
<!-- 表头 -->
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体内容 -->
<tbody>
<!-- //这里for(元素内容,元素序号)in 数组 -->
<!-- 这里v-for在tr标签中,tr标签只有一个,但是因为v-for的使用就会导致只要数组有多少个元素就会有多少个tr -->
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<!-- 因为gender是数字,所以需要判断一下,如果gender等于1,则返回男,否则返回女 -->
<td>{{e.gender == 1?'男' : '女'}}</td>
<!-- 插值表达式是不能出现在标签内部 -->
<!-- 这里使用了v-bind:因为图片只能使用v-bind:src,这里图片不能使用插值表达式 -->
<!-- alt图像加载失败时的替代显示 这里:alt其实是v-bind:alt 的简写-->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
<!-- v-if: 控制元素的显示与隐藏 -->
<!-- 这里e是for循环的元素,所以e.job是e这个元素的job属性 -->
<!-- 这里e.job == 1表示如果job等于1,则显示班主任,否则就一个一个下去哪个等于显示哪个 -->
<td>
<span v-if="e.job == 1">班主任</span>
<span v-else-if="e.job == 2">讲师</span>
<span v-else-if="e.job == 3">学工主管</span>
<span v-else-if="e.job == 4">教研主管</span>
<span v-else-if="e.job == 5">咨询师</span>
<span v-else>其他</span>
</td>
<!-- v-show表示元素的显示与隐藏,用处和v-if一样但是其是通过css里面的display:none隐藏 -->
<!-- v-show: 控制元素的显示与隐藏 -->
<!-- <td>
<span v-show="e.job == 1">班主任</span>
<span v-show="e.job == 2">讲师</span>
<span v-show="e.job == 3">学工主管</span>
<span v-show="e.job == 4">教研主管</span>
<span v-show="e.job == 5">咨询师</span>
</td> -->
<td>{{e.entrydate}}</td>
<td>{{e.updatetime}}</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
<!-- 页脚版权区域 -->
<footer class="footer">
<p>江苏传智播客教育科技股份有限公司</p>
<p>版权所有 Copyright 2006-2024 All Rights Reserved</p>
</footer>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
// 引用Vue框架
createApp({
data() {
return {
//这里是上面导航栏所搜索的集合
searchForm: { //封装用户输入的查询条件
name: '',
gender: '',
job: ''
},
//empList中[]表示数组,{}表示对象
empList: [
{ "id": 1,
"name": "谢逊",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/4.jpg",
"gender": 1,
"job": "1",
"entrydate": "2023-06-09",
"updatetime": "2024-09-30T14:59:38"
},
{
"id": 2,
"name": "韦一笑",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg",
"gender": 1,
"job": "1",
"entrydate": "2020-05-09",
"updatetime": "2024-09-01T00:00:00"
},
{
"id": 3,
"name": "黛绮丝",
"image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/2.jpg",
"gender": 2,
"job": "2",
"entrydate": "2021-06-01",
"updatetime": "2024-09-01T00:00:00"
}
]
}
},
//V-on使用方法的定义
methods: {
search(){
//将搜索条件, 输出到控制台
console.log(this.searchForm);
},
clear(){
//清空表单项数据
this.searchForm = {name:'', gender:'', job:''}
}
},
}).mount('#container')//mount表示上面的操作运用在id为container的元素上,即本页的div
</script>
</body>
</html>
html

Ajax
了解Ajax

异步交互概念

就是一部分请求已经接收并使用但是全部请求并没有全部展示
以上图片之中提示词已经出来了但是页面没有反应
同步与异步

Axios

函数解释
url:请求的网址
data: Whenever the request method is POST, the data to be retrieved consists of (are you requesting textual data or password data?)
param:在采用GET方法时从URL中获取的参数。例如,在QQ登录时用户输入账号和密码后点击登录按钮,则系统会将用户的账号和密码信息传送给服务器进行验证。
成功回调函数和失败回调函数
当在成功访问时会触发相应的函数,在这种情况下系统会显示成功提示或失败信息。
在无法成功登录时会调用的函数比如无法完成QQ登录会提示网络连接错误信息
请求方式案例语法
<!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>
</head>
<body>
<input type="button" value="获取数据GET" id="btnGet">
<input type="button" value="操作数据POST" id="btnPost">
<script src="js/axios.js"></script>
<script>
//发送GET请求
document.querySelector('#btnGet').addEventListener('click', () => {
//axios发起异步请求
axios({
url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/list',
method: 'GET'
}).then((result) => { //成功回调函数
console.log(result.data);
}).catch((err) => { //失败回调函数
console.log(err);
})
})
//发送POST请求
document.querySelector('#btnPost').addEventListener('click', () => {
//axios发起异步请求
axios({
url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/update',
method: 'POST',
data: 'id=1' //POST请求方式 , 请求体
}).then((result) => { //成功回调函数
//result.data表示返回对象之中的data数据
console.log(result.data);
}).catch((err) => { //失败回调函数
console.log(err);
})
})
</script>
</body>
</html>
html

结果

以上方式复杂以下是简写方式

Axios别名
<!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>
</head>
<body>
<input type="button" value="获取数据GET" id="btnGet">
<input type="button" value="操作数据POST" id="btnPost">
<script src="js/axios.js"></script>
<script>
//发送GET请求
document.querySelector('#btnGet').addEventListener('click', () => {
axios.get('https://mock.apifox.cn/m1/3083103-0-default/emps/list').then((result) => {
console.log(result.data);
});
// 这里输出窗口第一行是======第二行才是数据,因为这是异步交互
// 异步交互访问的时候会先执行下面的代码,等到返回数据的时候就会自己输出
console.log('==========================');
})
//发送POST请求
document.querySelector('#btnPost').addEventListener('click', () => {
//这里的id=1是请求体,是请求id为1的数据
axios.post('https://mock.apifox.cn/m1/3083103-0-default/emps/update', 'id=1').then((result) => {
console.log(result.data);
});
})
</script>
</body>
html

Axios对Tlias智能学习辅助系统案例改造
第一步引入Axios
<script src="js/axios.js"></script>
html
第二步改造searchForm和emplist
empList: []
将emplist中数据清空
javascript
使用ajax数据访问服务器得到数据随后通过输入来查找数据
async search(){
// 发送ajax请求,获取数据
// axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then((result) => {
// this.empList = result.data.data;
// })
// console.log('===========================');
let result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);
this.empList = result.data.data;
},
javascript

clear(){
//清空表单项数据
this.searchForm = {name:'', gender:'', job:''}
this.search()
}
这里是按清空按钮时的反应
javascript
为了代码的可维护性这里异步改同步
同步异步加深认识

此处将执行异步操作改为同步流程,在执行异步操作时,在被调用的过程中会立即运行下面的代码段,并在该操作完成并返回结果后才进行下一步处理;而同步流程则会在当前处理完成之后才会继续执行后续的逻辑步骤


mounted(){
//页面加载完成之后,发送ajax请求,获取数据
this.search()
}
javascript
改完以后的案例代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Tlias智能学习辅助系统</title>
<style>
/* 导航栏样式 */
.navbar {
background-color: #b5b3b3; /* 灰色背景 */
display: flex; /* flex弹性布局 */
justify-content: space-between; /* 左右对齐 */
padding: 10px; /* 内边距 */
align-items: center; /* 垂直居中 */
}
.navbar h1 {
margin: 0; /* 移除默认的上下外边距 */
font-weight: bold; /* 加粗 */
color: white;
/* 设置字体为楷体 */
font-family: "楷体";
}
.navbar a {
color: white; /* 链接颜色为白色 */
text-decoration: none; /* 移除下划线 */
}
/* 搜索表单样式 */
.search-form {
display: flex;
flex-wrap: nowrap;
align-items: center;
gap: 10px; /* 控件之间的间距 */
margin: 20px 0;
}
.search-form input[type="text"], .search-form select {
padding: 5px; /* 输入框内边距 */
width: 260px; /* 宽度 */
}
.search-form button {
padding: 5px 15px; /* 按钮内边距 */
}
/* 表格样式 */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd; /* 边框 */
padding: 8px; /* 单元格内边距 */
text-align: center; /* 左对齐 */
}
th {
background-color: #f2f2f2;
font-weight: bold;
}
.avatar {
width: 30px;
height: 30px;
}
/* 页脚样式 */
.footer {
background-color: #b5b3b3; /* 灰色背景 */
color: white; /* 白色文字 */
text-align: center; /* 居中文本 */
padding: 10px 0; /* 上下内边距 */
margin-top: 30px;
}
#container {
width: 80%; /* 宽度为80% */
margin: 0 auto; /* 水平居中 */
}
</style>
</head>
<body>
<div id="container">
<!-- 顶部导航栏 -->
<div class="navbar">
<h1>Tlias智能学习辅助系统</h1>
<a href="#">退出登录</a>
</div>
<!-- 搜索表单区域 -->
<form class="search-form">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名">
<label for="gender">性别:</label>
<select id="gender" name="gender" v-model="searchForm.gender">
<option value=""></option>
<option value="1">男</option>
<option value="2">女</option>
</select>
<label for="position">职位:</label>
<select id="position" name="position" v-model="searchForm.job">
<option value=""></option>
<option value="1">班主任</option>
<option value="2">讲师</option>
<option value="3">学工主管</option>
<option value="4">教研主管</option>
<option value="5">咨询师</option>
</select>
<button type="button" v-on:click="search">查询</button>
<button type="button" @click="clear">清空</button>
</form>
<!-- 表格展示区 -->
<table>
<!-- 表头 -->
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>头像</th>
<th>职位</th>
<th>入职日期</th>
<th>最后操作时间</th>
<th>操作</th>
</tr>
</thead>
<!-- 表格主体内容 -->
<tbody>
<tr v-for="(e, index) in empList" :key="e.id">
<td>{{index + 1}}</td>
<td>{{e.name}}</td>
<td>{{e.gender == 1?'男' : '女'}}</td>
<!-- 插值表达式是不能出现在标签内部 -->
<td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td>
<!-- v-if: 控制元素的显示与隐藏 -->
<td>
<span v-if="e.job == 1">班主任</span>
<span v-else-if="e.job == 2">讲师</span>
<span v-else-if="e.job == 3">学工主管</span>
<span v-else-if="e.job == 4">教研主管</span>
<span v-else-if="e.job == 5">咨询师</span>
<span v-else>其他</span>
</td>
<!-- v-show: 控制元素的显示与隐藏 -->
<!-- <td>
<span v-show="e.job == 1">班主任</span>
<span v-show="e.job == 2">讲师</span>
<span v-show="e.job == 3">学工主管</span>
<span v-show="e.job == 4">教研主管</span>
<span v-show="e.job == 5">咨询师</span>
</td> -->
<td>{{e.entrydate}}</td>
<td>{{e.updatetime}}</td>
<td class="action-buttons">
<button type="button">编辑</button>
<button type="button">删除</button>
</td>
</tr>
</tbody>
</table>
<!-- 页脚版权区域 -->
<footer class="footer">
<p>江苏传智播客教育科技股份有限公司</p>
<p>版权所有 Copyright 2006-2024 All Rights Reserved</p>
</footer>
</div>
<script src="js/axios.js"></script>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
searchForm: { //封装用户输入的查询条件
name: '',
gender: '',
job: ''
},
empList: []
}
},
//方法
methods: {
async search(){
// 发送ajax请求,获取数据
// axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then((result) => {
// this.empList = result.data.data;
// })
// console.log('===========================');
let result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);
this.empList = result.data.data;
},
clear(){
//清空表单项数据
this.searchForm = {name:'', gender:'', job:''}
this.search()
}
},
//钩子函数
mounted(){
//页面加载完成之后,发送ajax请求,获取数据
this.search()
}
}).mount('#container')
</script>
</body>
</html>
html

Maven


MVN的安装

MVN的验证

使用mvn -v查看是否有版本
此处没有说Mvn与IDE配置需要自行看视频第33集
Mvn的目录结构

第一个Mvn项目的创建

package com.itheima;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Maven ~");
}
}
java
Mvn的坐标
用来引用所需要的资源包

导入Mvn项目至IDE



看到以后你会发现导入以后第二个项目颜色会变粗

依赖配置


依赖传递

下载一个包会将这个包里所涉及的依赖都下载下来



这里install时clean不会,因为不属于同一套生命周期
尝试使用生命周期

clean是删除target目录,comperter是创先target目录





案例

main下面的就是一个方法
test就是一个测试类其使用Junit进行测试
具体代码如下
package com.itheima;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
public class UserService {
/** * 给定一个身份证号, 计算出该用户的年龄
* @param idCard 身份证号
*/
public Integer getAge(String idCard){
if (idCard == null || idCard.length() != 18) {
throw new IllegalArgumentException("无效的身份证号码");
}
String birthday = idCard.substring(6, 14);
LocalDate parse = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyyMMdd"));
return Period.between(parse, LocalDate.now()).getYears();
}
/** * 给定一个身份证号, 计算出该用户的性别
* @param idCard 身份证号
*/
public String getGender(String idCard){
if (idCard == null || idCard.length() != 18) {
throw new IllegalArgumentException("无效的身份证号码");
}
return Integer.parseInt(idCard.substring(16,17)) % 2 == 1 ? "男" : "女";
}
}
java

Test
package com.itheima;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
/** * 测试类
*/
@DisplayName("用户信息测试类")
public class UserServiceTest {
/*@BeforeAll //在所有的单元测试方法之前, 一次
public static void beforeAll(){
System.out.println("before All");
}
@AfterAll //在所有的单元测试方法之后, 一次
public static void afterAll(){
System.out.println("after All");
}
@BeforeEach //在每一个单元测试方法之前, 都会一次
public void beforeEach(){
System.out.println("before Each");
}
@AfterEach //在每一个单元测试方法之后, 都会一次
public void afterEach(){
System.out.println("after Each");
}*/
@Test
public void testGetAge(){
UserService userService = new UserService();
Integer age = userService.getAge("100000200010011011");
System.out.println(age);
}
@Test
public void testGetGender(){
UserService userService = new UserService();
String gender = userService.getGender("100000200010011011");
System.out.println(gender);
}
/** * 断言
*/
@Test
public void testGenderWithAssert(){
UserService userService = new UserService();
String gender = userService.getGender("100000200010011011");
//断言
//Assertions.assertEquals("男", gender);
Assertions.assertEquals("男", gender, "性别获取错误有问题");
}
/** * 断言
*/
@Test
public void testGenderWithAssert2(){
UserService userService = new UserService();
//断言
Assertions.assertThrows(IllegalArgumentException.class, () -> {
userService.getGender(null);
});
}
/** * 参数化测试
*/
@DisplayName("测试用户性别")
@ParameterizedTest
@ValueSource(strings = {"100000200010011011","100000200010011031","100000200010011051"})
public void testGetGender2(String idCard){
UserService userService = new UserService();
String gender = userService.getGender(idCard);
//断言
Assertions.assertEquals("男", gender);
}
}
java

单元测试绿色并不意味着其实完全没有问题;因为它只是成功运行了;但输出的结果是否符合预期却无法确定。

断言的两种方式
/** * 断言
*/
@Test
public void testGenderWithAssert(){
UserService userService = new UserService();
String gender = userService.getGender("100000200010011011");
//断言
//Assertions.assertEquals("男", gender);
//gender表示实际的结果, expcted表示你希望输出的值,若是两值不相等 则会输出错误信息
Assertions.assertEquals("男", gender, "性别获取错误有问题");
}
/** * 断言
*/
@Test
public void testGenderWithAssert2(){
UserService userService = new UserService();
//断言
//这里是异常断言,意思就是若是报错是IllegalArgumentException异常,则测试通过,
//测试通过是什么都不输出并且是绿钩
Assertions.assertThrows(IllegalArgumentException.class, () -> {
userService.getGender(null);
});
}
java


以上方法使用
/*@BeforeAll //在所有的单元测试方法之前, 一次,其所用方法必须是静态方法
public static void beforeAll(){
System.out.println("before All");
}
@AfterAll //在所有的单元测试方法之后, 一次,其所用方法必须是静态方法
public static void afterAll(){
System.out.println("after All");
}
@BeforeEach //在每一个单元测试方法之前, 都会一次
public void beforeEach(){
System.out.println("before Each");
}
@AfterEach //在每一个单元测试方法之后, 都会一次
public void afterEach(){
System.out.println("after Each");
}*/
java

/** * 参数化测试
*/
@DisplayName("测试用户性别")
//DisplayName表示测试类中的哪个部分,当你测试的时候可以很好的知道你在测试什么
@ParameterizedTest
//ParameterizedTest表示参数化测试,就是可以一次性测试多个数据
//下面表示使用的时候几个参数会带入到下列的式子里面一个一个测试
@ValueSource(strings = {"100000200010011011","100000200010011031","100000200010011051"})
public void testGetGender2(String idCard){
UserService userService = new UserService();
String gender = userService.getGender(idCard);
//断言
Assertions.assertEquals("男", gender);
}
java


在传入身份证的时候是否能说明这个方法没有问题呢?
不可行的原因在于输入的身份证不完整。举例说明不够全面,则必须涵盖所有可能的情况。

测试代码书写
package com.itheima;
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
public class UserServiceAiTest {
private UserService userService;
@BeforeEach // 在每个测试方法执行前执行
public void setUp() {
userService = new UserService();
}
@Test
public void getGender_ValidMaleIdCard_ReturnsMale() {
String gender = userService.getGender("100000200010011011");
assertEquals("男", gender, "性别获取错误,应为男性");
}
@Test
public void getGender_ValidFemaleIdCard_ReturnsFemale() {
String gender = userService.getGender("100000200010011022");
assertEquals("女", gender, "性别获取错误,应为女性");
}
@Test
public void getGender_NullIdCard_ThrowsException() {
assertThrows(IllegalArgumentException.class, () -> {
userService.getGender(null);
}, "无效的身份证号码");
}
@Test
public void getGender_InvalidLengthIdCard_ThrowsException() {
assertThrows(IllegalArgumentException.class, () -> {
userService.getGender("10000020001001101");
}, "无效的身份证号码");
}
@ParameterizedTest
@ValueSource(strings = {"100000200010011011", "100000200010011031", "100000200010011051"})
public void getGender_MultipleMaleIdCards_ReturnsMale(String idCard) {
String gender = userService.getGender(idCard);
assertEquals("男", gender, "性别获取错误,应为男性");
}
@ParameterizedTest
@ValueSource(strings = {"100000200010011022", "100000200010011042", "100000200010011062"})
public void getGender_MultipleFemaleIdCards_ReturnsFemale(String idCard) {
String gender = userService.getGender(idCard);
assertEquals("女", gender, "性别获取错误,应为女性");
}
}
java

在进行测试时想到测试可能无法全面覆盖所有情况,此时有一个工具能够显示我们的覆盖率情况。

第三个就是测试覆盖率的

