👉 在线笔记:https://du1in9.github.io/javaweb.github.io/
第1章 - HTML & CSS & JS
1.1 HTML & CSS
1.1.1 快速入门
Web标准:HTML:负责网页的结构;CSS:负责网页的表现;JS:负责网页的行为
<html>
<head>
<title>标题</title>
</head>
<body>
正文
</body>
</html>
1.1.2 开发工具
Visual Studio Code(简称 VS Code )是 Microsoft 于2015年4月发布的一款代码编辑器。
VS Code 提供了非常强大的插件库,大大提高了开发效率。
1.1.3 基础标签
- 标题标签:<h1>…</h1>(h1 → h6 重要程度依次降低)
- 水平线标签:<hr>
- 图片标签:<img src="…" width="…" height="…">
<!--
img标签:
src: 图片资源路径
width: 宽度(px, 像素 ; % , 相对于父元素的百分比)
height: 高度(px, 像素 ; % , 相对于父元素的百分比)
<img src="img/news_logo.png" width="80%" >
绝对路径:
1. 绝对磁盘路径: C:\Users\Administrator\Desktop\HTML\img\news_logo.png
2. 绝对网络路径: https://i2.sinaimg.cn/dy/deco/2012/0613/yocc20120613img01/news_logo.png
相对路径:
./ : 当前目录 , ./ 可以省略
../: 上一级目录
-->
<!-- 文档类型为HTML -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 字符集为UTF-8 -->
<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>焦点访谈:中国底气 新思想夯实大国粮仓</title>
</head>
<body>
<img src="img/news_logo.png"> 新浪政务 > 正文
<h1>焦点访谈:中国底气 新思想夯实大国粮仓</h1>
<hr>
2023年03月02日 21:50 央视网
<hr>
</body>
</html>
- CSS引入方式:行内样式,内嵌样式,外联样式
- 颜色表示:关键字,rgb表示法,十六进制
- 颜色属性:color: 设置文本内容的颜色
<head>
<!-- 方式2: 内嵌样式 -->
<style>
h1 {color: #4D4F53;}
</style>
<!-- 方式3: 外联样式 -->
<!-- <link rel="stylesheet" href="css/news.css"> -->
</head>
<body>
<!-- 方式1: 行内样式 -->
<!-- <h1 style="color: red;">焦点访谈:中国底气 新思想夯实大国粮仓</h1> -->
</body>
- <span>标签:是一个在开发网页时大量会用到的没有语义的布局标签
- CSS选择器:优先级:id选择器 > 类选择器 > 元素选择器
- CSS属性:font-size:字体大小
<style>
/* 元素选择器 */
span {color: red;}
/* 类选择器 */
.cls {color: green;}
/* ID选择器 */
#time {font-size: 13px;}
</style>
<span class="cls" id="time">2023年03月02日 21:50</span> <span class="cls">央视网</span>
-
超链接:标签:<a>
属性:href:指定资源访问的url,target:指定在何处打开资源链接
_self:默认值,在当前页面打开,_blank:在空白页面打开
CSS属性:text-decoration:规定添加到文本的修饰,none表示定义标准的文本
<style>
a {
color: black;
text-decoration: none; /* 设置文本为一个标准的文本 */
}
</style>
<img src="img/news_logo.png"> <a href="http://gov.sina.com.cn/" target="_self">新浪政务</a>
<span> <a href="https://news.cctv.com/2023/03/02/ARTIUCKFf9kE9eXgYE46ugx3230302.shtml" target="_blank">央视网</a></span>
- 音频、视频标签:<audio> <video>
- 换行、段落标签:换行:<br> ; 段落:<p>
- 文本加粗标签:<b> <strong>
- CSS样式:line-height,text-indent,text-align
- 注意:无论输入多少个空格,只会显示一个。 可以使用空格占位符: 
<style>
p {
text-indent: 35px; /* 设置首行缩进 */
line-height: 40px; /* 设置行高 */
}
#plast {
text-align: right; /* 对齐方式 */
}
</style>
<p><strong>央视网消息</strong>...</p>
<p id="plast">责任编辑:王树淼 SN242</p>
CSS盒子模型:内容(content)、内边距(padding)、边框(border)、外边距(margin)
-
CSS属性:width、height、border、padding、margin
注意:如果只需要设置某一个方位的边框、内边距、外边距,可以在属性名后加上 – 位置
如:padding-top、padding-left、padding-right …
<style>
#center {
width: 65%;
/* margin: 0% 17.5% 0% 17.5% ; */ /* 上 右 下 左 */
margin: 0 auto;
}
</style>
<div id="center">
...(正文)
</div>
1.1.4 表格标签
<table border="1px" cellspacing="0" width="600px">
<tr>
<th>序号</th>
<th>品牌名称</th>
</tr>
<tr>
<td>1</td>
<td>华为</td>
</tr>
<tr>
<td>2</td>
<td>阿里</td>
</tr>
</table>
1.1.5 表单标签
<!--
action: 表单提交的url, 往何处提交数据 . 如果不指定, 默认提交到当前页面
method: 表单的提交方式 .
get: 在url后面拼接表单数据, 比如: ?username=Tom&age=12, 长度有限制 (默认值)
post: 在消息体(请求体)中传递的, 参数大小无限制的.
注意: 表单项必须有name属性才可以提交.
-->
<form action="" method="post">
用户名: <input type="text" name="username">
年龄: <input type="text" name="age">
<input type="submit" value="提交">
</form>
表单标签 - 表单项:
1.2 JavaScript
1.2.1 JS 介绍
- JavaScript(简称:JS) 是一门跨平台、面向对象的脚本语言。是用来控制网页行为的,它能使网页可交互。
- JavaScript 和 Java 是完全不同的语言,不论是概念还是设计。但是基础语法类似。
1.2.2 JS 引入方式
<!-- 内部脚本 -->
<script>alert("Hello JS");</script>
<!-- 外部脚本 -->
<script src="js/demo.js"></script>
1.2.3 JS 基础语法
- 输出语句
<script>
window.alert("Hello JS"); //弹出框
document.write("Hello JS"); //写入HTML页面
console.log("Hello JS"); //浏览器控制台
</script>
- 变量
<script>
// var 定义的是一个全局变量, 还可以重复声明
// let 定义的是一个局部变量, 不可以重复声明
{
var a = 0;
var a = "A";
let b = 1;
let b = "B"; // error
}
alert(a); // A
// const 定义的是一个常量
const pi = 3.14;
pi = 3.15;
alert(pi); // error
</script>
- 数据类型
<script>
//原始数据类型
alert(typeof 3); //number
alert(typeof 3.14); //number
alert(typeof "A"); //string
alert(typeof 'Hello'); //string
alert(typeof true); //boolean
alert(typeof false); //boolean
alert(typeof null); //object
var a ;
alert(typeof a); //undefined
</script>
- 运算符:算术运算符、赋值运算符、比较运算符、逻辑运算符、 三元运算符
<script>
// == 会进行类型转换,=== 不会进行类型转换
var age = 20;
var _age = "20";
var $age = 20;
alert(age == _age); //true
alert(age === _age); //false
alert(age === $age); //true
</script>
- 类型转换
<script>
// 类型转换 - 其他类型转为数字
alert(parseInt("12")); //12
alert(parseInt("1222A45")); //1222
alert(parseInt("A45")); //NaN
// 类型转换 - 其他类型转为 boolean
// Number: 0 和 NaN 为 false, 其他均转为 true
// String: 空字符串为 false, 其他均转为 true
// Null 和 undefined: 均转为 false
</script>
- 流程控制语句:if…else if …else…,switch,for ,while,do … while
1.2.4 JS 函数
<script>
// 定义函数-1
function add(a,b){
return a + b;
}
// 定义函数-2
var add = function(a,b){
return a + b;
}
alert(add(10,20,30,40)); // 30
</script>
1.2.5 JS 对象
- Array
<script>
// 定义数组
var arr = new Array(1,2,3,4);
var arr = [1,2,3,4];
console.log(arr[1]); // 2
// 特点: 长度可变 类型可变
arr[10] = 50;
console.log(arr[10]); // 50
console.log(arr[9]); // undifined
arr[8] = "A";
// forEach: 遍历数组中有值的元素
arr.forEach(function(e){
console.log(e); // 1 2 3 4 A 50
})
// ES6 箭头函数
arr.forEach((e) => {
console.log(e); // 1 2 3 4 A 50
})
//push: 添加元素到数组末尾
arr.push(7,8,9); // 1 2 3 4 A 50 7 8 9
//splice: 删除元素
arr.splice(2,2); // 1 2 A 50
</script>
- String
<script>
var str1 = new String("Hello String");
var str2 = " Hello String ";
console.log(str1.length); // 12
console.log(str1.charAt(4)); // o
console.log(str1.indexOf("lo")); // 3
console.log(str1.substring(0,5)); // hello
console.log(str2.trim()); // Hello String
</script>
-
JSON
JavaScript Object Notation(对象标记法)是通过 JavaScript 对象标记法书写的文本
由于其语法简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输
<script>
// 自定义对象
var user = {
name: "Tom",
age: 10,
eat1: function() {alert("用膳~");}
eat2() {alert("用膳~");}
}
alert(user.name);
user.eat2();
// 定义json
var jsonstr = '{"name":"Tom", "age":18, "addr":["北京","上海","西安"]}';
alert(jsonstr.name);
// json字符串--js对象
var obj = JSON.parse(jsonstr);
alert(obj.name);
// js对象--json字符串
alert(JSON.stringify(obj));
</script>
-
BOM
Browser Object Model(浏览器对象模型)允许JavaScript与浏览器对话, JavaScript 将浏览器的各个组成部分封装为对象:
Window 浏览器窗口对象、Navigator 浏览器对象、Screen 屏幕对象、History 历史记录对象、Location 地址栏对象
<script>
// window
window.alert("Hello BOM");
// location
location.href = "https://www.itcast.cn";
// confirm - 对话框
alert(confirm("您确认删除该记录吗?"));
//定时器 - setInterval -- 周期性的执行某一个函数
var i = 0;
setInterval(function(){
i++;
console.log("定时器执行了"+i+"次");
},2000);
//定时器 - setTimeout -- 延迟指定时间执行一次
setTimeout(function(){
alert("JS");
},3000);
</script>
- DOM
<body>
<img id="h1" src="img/off.gif"> <br><br>
<div class="cls">传智教育</div> <br>
<div class="cls">黑马程序员</div> <br>
<input type="checkbox" name="hobby"> 电影
<input type="checkbox" name="hobby"> 旅游
<input type="checkbox" name="hobby"> 游戏
</body>
<script>
// 1. 获取Element元素
// 1.1 获取元素-根据ID获取
var img = document.getElementById('h1');
// 1.2 获取元素-根据标签获取 - div
var divs = document.getElementsByTagName('div');
// 1.3 获取元素-根据name属性获取
var ins = document.getElementsByName('hobby');
// 1.4 获取元素-根据class属性获取
var divs2 = document.getElementsByClassName('cls');
// 2. 查询参考手册, 属性、方法
divs2[0].innerHTML = "传智教育666";
</script>
<script>
// a. 点亮灯泡 : src 属性值
img.src = "img/on.gif";
// b. 将所有div标签的内容后面加上: very good (红色字体)
for (let i = 0; i < divs.length; i++) {
const div = divs[i];
div.innerHTML += "<font color='red'>very good</font>";
}
// c. 使所有的复选框呈现选中状态
for (let i = 0; i < ins.length; i++) {
ins[i].checked = true;
}
</script>
1.2.6 JS 事件监听
<body>
<input type="button" id="btn1" value="事件绑定1" onclick="on()">
<input type="button" id="btn2" value="事件绑定2">
</body>
<script>
function on(){
alert("按钮1被点击了...");
}
document.getElementById('btn2').onclick = function(){
alert("按钮2被点击了...");
}
</script>
<script>
//onclick: 鼠标点击事件
function fn1() {console.log("我被点击了...");}
//onblur: 失去焦点事件
function bfn() {console.log("失去焦点...");}
//onfocus: 元素获得焦点
function ffn() {console.log("获得焦点...");}
//onload : 页面加载完成后触发
function load() {console.log("页面加载完成...")}
//onsubmit: 提交表单事件
function subfn() {alert("表单被提交了...");}
//onkeydown: 某个键盘的键被按下
function kfn() {console.log("键盘被按下了...");}
//onmouseover: 鼠标移动到元素之上
function over() {console.log("鼠标移入了...")}
//onmouseout: 鼠标移出某元素
function out() {console.log("鼠标移出了...")}
</script>
- 案例
<body>
<input type="button" value="点亮" onclick="on()">
<input type="text" id="name" value="ITCAST" onfocus="lower()">
<input type="button" value="全选" onclick="checkAll()">
</body>
<script>
// 1. 点击 "点亮" 按钮, 点亮灯泡
function on(){
var img = document.getElementById("light");
img.src = "img/on.gif";
}
// 2. 输入框聚焦后, 展示小写
function lower(){
var input = document.getElementById("name");
input.value = input.value.toLowerCase();
}
// 3. 点击 "全选" 按钮使所有的复选框呈现选中状态
function checkAll(){
var hobbys = document.getElementsByName("hobby");
for (let i = 0; i < hobbys.length; i++) {
hobbys[i].checked = true;
}
}
</script>
第2章 - Vue & Element
2.1 vue
2.1.1 Vue 概述
Vue 是一套前端框架,免除原生 JavaScript 中的 DOM 操作,简化书写
基于MVVM(Model-View-ViewModel)思想,实现数据的双向绑定,将编程的关注点放在数据上
2.1.2 Vue 快速入门
<head>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
</body>
<script>
new Vue({
el: "#app",
data:{
message: "Hello Vue"
}
})
</script>
2.1.3 Vue 指令
指令 | 作用 |
---|---|
v-bind | 为HTML标签绑定属性值,如设置 href , css样式等 |
v-model | 在表单元素上创建双向数据绑定 |
v-on | 为HTML标签绑定事件 |
v-if / else-if / else | 条件性的渲染某元素,判定为true时渲染,否则不渲染 |
v-show | 根据条件展示某元素,区别在于切换的是display属性的值 |
v-for | 列表渲染,遍历容器的元素或者对象的属性 |
<body>
<div id="app">
<table border="1" cellspacing="0" width="60%">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>成绩</th>
<th>等级</th>
</tr>
<tr align="center" v-for="(user,index) in users">
<td>{{index + 1}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>
<span v-if="user.gender == 1">男</span>
<span v-if="user.gender == 2">女</span>
</td>
<td>{{user.score}}</td>
<td>
<span v-if="user.score >= 85">优秀</span>
<span v-else-if="user.score >= 60">及格</span>
<span style="color: red;" v-else>不及格</span>
</td>
</tr>
</table>
</div>
</body>
<script>
new Vue({
el: "#app",
data: {
users: [{
name: "Tom",
age: 20,
gender: 1,
score: 78
},{
name: "Rose",
age: 18,
gender: 2,
score: 86
},{
name: "Jerry",
age: 26,
gender: 1,
score: 90
},{
name: "Tony",
age: 30,
gender: 1,
score: 52}
]
},
methods: {
},
})
</script>
2.1.4 生命周期
生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子)
状态 | 阶段周期 |
---|---|
beforeCreate | 创建前 |
created | 创建后 |
beforeMount | 挂载前 |
mounted | 挂载完成 |
beforeUpdate | 更新前 |
updated | 更新后 |
beforeDestroy | 销毁前 |
destroyed | 销毁后 |
<script>
new Vue({
el: "#app",
mounted () {
alert("vue挂载完成,发送请求到服务端")
}
})
</script>
2.1.5 Ajax
① Ajax 介绍
Asynchronous JavaScript And XML(异步的 JavaScript 和 XML)
- 数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想
② 原生 Ajax
<input type="button" value="获取数据" onclick="getData()">
<script>
function getData(){
//1. 创建XMLHttpRequest
var xmlHttpRequest = new XMLHttpRequest();
//2. 发送异步请求
xmlHttpRequest.open('GET','http://yapi.smart-xwork.cn/mock/169327/emp/list');
xmlHttpRequest.send();
//3. 获取服务响应数据
xmlHttpRequest.onreadystatechange = function(){
if(xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200){
document.getElementById('div1').innerHTML = xmlHttpRequest.responseText;
}
}
}
</script>
③ Axios
Axios 对原生的 Ajax 进行了封装,简化书写,快速开发
<head>
<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.get("http://yapi.smart-xwork.cn/mock/169327/emp/list").then(result => {
console.log(result.data);
})
}
function post(){ //通过axios发送异步请求-post
axios.post("http://yapi.smart-xwork.cn/mock/169327/emp/deleteById","id=1").then(result => {
console.log(result.data);
})
}
</script>
- 案例
<body>
<div id="app">
<table border="1" cellspacing="0" width="60%">
<tr>
<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 v-bind:src="emp.image" width="70px" height="50px">
</td>
<td>
<span v-if="emp.gender == 1">男</span>
<span v-if="emp.gender == 2">女</span>
</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 => {
this.emps = result.data.data;
})
}
});
</script>
2.1.6 前后台分离开发
① 介绍
② YAPI
YApi 是高效、易用、功能强大的 api 管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务
使用流程:添加项目 → 添加分类 → 添加接口
2.1.7 前端工程化
① 环境准备
前端工程化:是指在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、标准化
-
Vue-cli 是Vue官方提供的一个脚手架,用于快速生成一个 Vue 的项目模板
Vue-cli 提供了如下功能:统一的目录结构、本地调试、热部署、单元测试、集成打包上线
环境依赖:NodeJS
② Vue 项目简介
项目创建:命令行:
vue create vue-project01
,图形化界面:vue ui
目录结构:基于Vue脚手架创建出来的工程,有标准的目录结构,如下:
- 配置端口
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 7000,
}
})
③ Vue 开发流程
Vue 的组件文件以 .vue 结尾,每个组件由三个部分组成:<template> 、<script>、<style>
<!-- src\App.vue -->
<!-- 模板部分,由它生成 HTML 代码 -->
<template>
<div>
<h1>
{{message}}
</h1>
</div>
</template>
<!-- 控制模板的数据来源和行为 -->
<script>
export default{
data(){
return{
message:"hello vue!"
}
}
}
</script>
<!-- css样式部分 -->
<style>
</style>
2.2 Element
2.2.1 Element 介绍
Element:是饿了么团队研发的,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
2.2.2 快速入门
-
安装 ElementUI 组件库 (在当前工程的目录下)
在命令行执行指令:
npm install element-ui@2.15.3
-
引入 ElementUI 组件库
// src\main.js import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
-
访问官网,复制组件代码,调整
<template> <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> </template> <script> export default { } </script>
<!-- src\App.vue --> <template> <element-view></element-view> </template> <script> import ElementView from './views/element/ElementView.vue' export default { components: { ElementView }, } </script>
2.2.3 Element 组件
-
Table 表格:用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
<template> <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> </template> <script> export default { data() { return { tableData: [{ date: "2016-05-02", name: "王小虎", address: "上海市普陀区金沙江路 1518 弄", }] }; } </script>
-
Pagination 分页:当数据量过多时,使用分页分解数据。
<template> <el-pagination background layout="total,sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="1000"> </el-pagination> </template> <script> export default { data() { return { methods: { handleSizeChange:function(val){ alert("每页记录数变化" + val) }, handleCurrentChange:function(val){ alert("页码发生变化" + val) } } } }; </script>
-
Dialog 对话框:在保留当前页面状态的情况下,告知用户并承载相关操作。
<template> <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="地址"></el-table-column> </el-table> </el-dialog> </template> <script> export default { data() { return { gridData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], dialogTableVisible: false } }; </script>
-
Form 表单:由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
<template> <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> </el-dialog> </template> <script> export default { data() { return { form: { name: '', region: '' }, dialogFormVisible: false }; }, methods: { onSubmit:function(){ alert(JSON.stringify(this.form)); } } }; </script>
2.2.4 Vue 路由
① 路由介绍
Vue Router 是 Vue 的官方路由
② 路由入门
<!-- src/App.vue-->
<router-view></router-view>
<!-- src/views/tlias/DeptView.vue -->
<router-link to="/dept">部门管理</router-link>
<router-link to="/emp">员工管理</router-link>
<!-- src/views/tlias/EmpView.vue -->
<router-link to="/dept">部门管理</router-link>
<router-link to="/emp">员工管理</router-link>
// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/emp',
name: 'emp',
component: () => import('../views/tlias/EmpView.vue')
},
{
path: '/dept',
name: 'dept',
component: () => import('../views/tlias/DeptView.vue')
},
{
path: '/',
redirect: '/dept'
}
]
2.2.5 打包部署
① 前端工程打包
② 前端工程部署
Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器
其特点是占有内存少,并发能力强,在各大型互联网公司都有非常广泛的使用
- 部署:将打包好的 dist 目录下的文件,复制到 nginx 安装目录的html目录下
- 启动:双击 nginx.exe 文件即可,Nginx服务器默认占用 80 端口号
注意事项:Nginx 默认占用80端口号,如果80端口号被占用,可以在 nginx.conf 中修改端口号。(netstat –ano | findStr 80
)
第3章 - Maven & 高级
3.1 Maven
3.1.1 课程介绍
3.1.2 Maven 概述
① Maven 介绍
Maven 是 apache 旗下的一个开源项目,是一款用于管理和构建 java 项目的工具
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
- 统一项目结构:提供标准、统一的项目结构
- 项目构建:标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式
② Maven 安装
解压 apache-maven-3.6.1-bin.zip
-
配置本地仓库:修改 conf/settings.xml 中的 <localRepository> 为一个指定目录:
<localRepository>C:\Develop\apache-maven-3.6.1\mvn_repo</localRepository>
-
配置阿里云私服:修改 conf/settings.xml 中的 <mirrors> 标签,为其添加如下子标签:
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
配置环境变量: MAVEN_HOME 为 maven 的解压目录,并将其 bin 目录加入 PATH 环境变量:
%MAVEN_HOME%\bin
测试:
mvn -v
3.1.3 IDEA 集成 Maven
① 配置 Maven 环境
配置 Maven 环境 (全局)
② 创建 Maven 项目
-
什么是坐标?
Maven 中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置。
使用坐标来定义项目或引入项目中需要的依赖。
-
Maven 坐标主要组成
groupId:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
artifactId:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
version:定义当前项目版本号
③ 导入 Maven 项目
3.1.4 依赖管理
① 依赖配置
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
注意事项
- 如果引入的依赖,在本地仓库不存在,将会连接远程仓库/中央仓库,然后下载依赖(这个过程会比较耗时,耐心等待)
- 如果不知道依赖的坐标信息,可以到 https://mvnrepository.com 中搜索
② 依赖传递
依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
<!-- maven-projectA\pom.xml -->
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven-projectB</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!-- maven-projectB\pom.xml -->
<dependencies>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven-projectC</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
<!-- maven-projectC\pom.xml -->
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
排除依赖:指主动断开依赖的资源,被排除的资源无需指定版本
<!-- maven-projectA\pom.xml -->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>maven-projectB</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 排除依赖 -->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
③ 依赖范围
依赖的 jar 包,默认情况下可以在任何地方使用。可以通过 <scope>…</ scope > 设置其作用范围
scope值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | Y | junit | ||
provided | Y | Y | servlet-api | |
runtime | Y | Y | jdbc驱动 |
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
④ 生命周期
Maven中有3套相互独立的生命周期:
- clean:清理工作(clean)
- default:核心工作,如:编译、测试、打包、安装(compile、test、package、install)
- site:生成报告、发布站点等
注意事项:在同一套生命周期中,当运行后面的阶段时,前面的阶段都会运行
3.2 Maven 高级
3.2.1 分模块设计与开发
将项目按照功能拆分成若干个子模块,方便项目的管理维护、扩展,也方便模块间的相互调用,资源共享
实践:
- 创建 maven 模块 tlias-pojo,存放实体类
- 创建 maven 模块 tlias-utils,存放相关工具类
<!-- tlias-web-management\pom.xml -->
<dependency>
<groupId>com.itheima</groupId>
<artifactId>tlias-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.itheima</groupId>
<artifactId>tlias-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
3.2.2 继承与聚合
① 继承
- 概念:继承描述的是两个工程间的关系,与 java 中的继承相似,子工程可以继承父工程中的配置信息,常见于依赖关系的继承
- 作用:简化依赖配置、统一管理依赖
-
创建 maven 模块 tlias-parent ,该工程为父工程,设置打包方式 pom(默认 jar)
<!-- tlias-parent\pom.xml --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.itheima</groupId> <artifactId>tlias-parent</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <!-- jar: 普通模块打包, springboot 项目基本都是 jar 包 (内嵌 tomcat 运行) --> <!-- war: 普通web程序打包, 需要部署在外部的 tomcat 服务器中运行 --> <!-- pom: 父工程或聚合工程, 该模块不写代码, 仅进行依赖管理 -->
-
在子工程的 pom.xml 文件中,配置继承关系
<!-- tlias-pojo\pom.xml --> <!-- tlias-utils\pom.xml --> <!-- tlias-web-management\pom.xml --> <parent> <groupId>com.itheima</groupId> <artifactId>tlias-parent</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../tlias-parent/pom.xml</relativePath> </parent>
-
在父工程中配置各个工程共有的依赖(子工程会自动继承父工程的依赖)
<!-- tlias-parent\pom.xml --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency>
-
版本锁定
在 maven 中,可以在父工程的 pom 文件中通过
<dependencyManagement>
来统一管理依赖版本<!-- tlias-parent\pom.xml --> <properties> <jjwt.version>0.9.1</jjwt.version> ... </properties> <dependencyManagement> <dependencies> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jjwt.version}</version> </dependency> ... </dependencies> </dependencyManagement>
<dependencyManagement> 与 <dependencies> 的区别:
- <dependencies> 是直接依赖, 在父工程配置了依赖, 子工程会直接继承下来。
- <dependencyManagement> 是统一管理依赖版本, 不会直接依赖, 还需要在子工程中引入所需依赖 (无需指定版本)
② 聚合
聚合工程中所包含的模块,在构建时,会自动根据模块间的依赖关系设置构建顺序,与聚合工程中模块的配置书写位置无关
<!-- tlias-parent\pom.xml -->
<modules>
<module>../tlias-pojo</module>
<module>../tlias-utils</module>
<module>../tlias-web-management</module>
</modules>
③ 对比
- 作用
- 聚合用于快速构建项目
- 继承用于简化依赖配置、统一管理依赖
- 相同点
- 聚合与继承的 pom.xml 文件打包方式均为 pom,可以将两种关系制作到同一个 pom 文件中
- 聚合与继承均属于设计型模块,并无实际的模块内容
- 不同点
- 聚合是在聚合工程中配置关系,聚合可以感知到参与聚合的模块有哪些
- 继承是在子模块中配置关系,父模块无法感知哪些子模块继承了自己
3.2.3 私服
私服是一种特殊的远程仓库,架设在局域网内,用来代理位于外部的中央仓库,用于解决团队内部的资源共享与资源同步问题
私服在企业项目开发中,一个项目 / 公司,只需要一台即可(无需我们自己搭建,会使用即可)
资源上传与下载:
- RELEASE(发行版本):功能趋于稳定、当前更新停止,可以用于发行的版本,存储在私服中的 RELEASE 仓库中
- SNAPSHOT(快照版本):功能不稳定、尚处于开发中的版本,即快照版本,存储在私服的 SNAPSHOT 仓库中
-
设置私服的访问用户名 / 密码
<!-- C:\Develop\apache-maven-3.6.1\conf\settings.xml --> <server> <id>maven-releases</id> <username>admin</username> <password>admin</password> </server> <server> <id>maven-snapshots</id> <username>admin</username> <password>admin</password> </server>
-
IDEA 的 maven 工程的 pom 文件中配置上传(发布)地址
<!-- tlias-parent\pom.xml --> <distributionManagement> <repository> <id>maven-releases</id> <url>http://192.168.150.101:8081/repository/maven-releases/</url> </repository> <snapshotRepository> <id>maven-snapshots</id> <url>http://192.168.150.101:8081/repository/maven-snapshots/</url> </snapshotRepository> </distributionManagement>
-
设置私服依赖下载的仓库组地址
在 mirrors 标签中,配置私服的连接地址 (如果之前配置过阿里云,需要直接替换掉)
<!-- C:\Develop\apache-maven-3.6.1\conf\settings.xml --> <mirror> <id>maven-public</id> <mirrorOf>*</mirrorOf> <url>http://192.168.150.101:8081/repository/maven-public/</url> </mirror>
在 profiles 标签中,增加如下配置,来指定 snapshot 快照版本的依赖,依然允许使用
<!-- C:\Develop\apache-maven-3.6.1\conf\settings.xml --> <profile> <id>allow-snapshots</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>maven-public</id> <url>http://192.168.150.101:8081/repository/maven-public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> </profile>
发布项目,直接运行 deploy 生命周期即可 (发布时,建议跳过单元测试)
参考链接:https://www.bilibili.com/video/BV1m84y1w7Tb?p=1&vd_source=ed621eaa6bcf9bf6acb7d0527c30489a