前端入门

HTML与CSS

HTML

HTML是什么:即HyperText Markup language 超文本标记语言,HTML的作用是定义网页的内容和结构

  • HyperText是指用超链接方式组织的网页,把网页联系起来
  • Markup是指用<标签>的方式赋予内容不同功能和含义

html由一系列元素构成:<p></p>称为起始和结束标签

被标签包围的被称为内容

元素内部还能有属性

<div id="div1" class="class_div"></div>

元素之间还可以嵌套(嵌套不能交叉

<!DOCTYPE html>
<html>
    <head>
        ...
    </head>
    <body>
        ...
    </body>
</html>

<!DOCTYPE html> 为文档声明,告诉浏览器如何加载该文档,以标准模式加载html

  • head 元素包含的是那些不用于展示内容的元素,如title,link,meta等
  • body 元素包含了对用户展现内容的元素,例如后面会学到的用于展示文本,图片,视频,音频的各种元素

空元素

<!--展示图片,src为图片地址-->
<img src="test.png"/>

vscode快捷键生成html:输入! + tab键

Anchor元素

超链接

<a href="网页地址">超链接文本</a>

#页面锚点,使用#号
<a href="#p1">跳转页面锚点</a>
<p id="p1">...</p>

#跳转顶部
<a href="#">回到顶部</a>

多媒体

Image

src格式有三种

文件地址

data URL

<img src="data:image/png;base64,数据">

data 媒体类型 base64,数据

Video

controls:播放控制条

<video src="视频文件地址" controls></video>

Audio

<audio src="音频文件地址" controls></audio>

更多元素参考mdn网站

网址:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a

表单

表单的作用:收集用户填入的数据,并将这些数据提交给服务器

<form action="服务器地址" method="请求方式" enctype="数据格式">
    <!--表单项-->
    <input type="submit" value="提交按钮">
</form>
  • method请求方式有
    • get(默认)提交时,数据跟在URL地址之后
    • post提交时,数据在请求体内
  • enctype在post请求时,指定数据的格式
    • application/x-www-form-urlcencoded(默认)
    • multipart/form-data
  • 其中表单项提供多种收集数据的方式
    • 有name属性的表单项数据,才会被发送给服务器

日期

在后端接收日期的时候需要指定和前端日期格式对应

使用**@DateTimeFormat**注解

@DateTimeFormat(pattern= "yyyy-MM-dd")
private LocalDate birthday;

文件上传

<input type="file" name="testFile">
  • 文件上传对form表单有特殊要求
<form action="..." method="post" enctype="multipart/form-data">
    ...
</form>
  • 服务端处理图片

MultipartFile 接收上传的文件数据

@RequestMapping("/test")
@ResponseBody
public String test(MultipartFile testFile){
    System.out.println("testFile:" + testFile.getSize());
    return "收到数据";
}

http请求

请求分三部分组成

  • 请求行: 声明了请求的方式,请求的uri地址,http协议
  • 请求头: 规定了本次请求的一些基本信息
  • 请求体: 本次请求携带的主要数据

session原理

Http无状态,有会话

  • 无状态是指,请求之间互相独立,第一次请求的数据,第二次请求不能重用

  • 有会话是指,客户端和服务端都有相应的技术,可以暂存数据,让数据在请求间共享

服务端使用了session技术来暂存数据,客户端会保存本次session的cookie,JSESSIONID

@RequestMapping("/s2")
@ResponseBody
public String s2(HttpSession session){
    return "取出数据" + session.getAttribute("name");
}

jwt原理(token)

返回的是一个加密生成后的令牌(token),返回给客户端

下次请求会携带token,服务端校验token,校验无误,放行

  • 更适用于分布式架构

token一般存放在请求头Authorization

@RequestMapping("/testToken")
@ResponseBody
public String testToken(String name,String password){
    //这里做个伪验证
    if ("zhangsan".equals(name) && "123".equals(password)){
        
        String token = Jwts.builder().setSubject(name).signWith(key).compact();
        
        return "验证身份通过" + token;
    
    }else {
    
        return "身份验证失败";
    
    }
}


@RequestMapping("/testToken2")
@ResponseBody
public String testToken2(@RequestHeader String authorization){
    
    try{
        
        System.out.println(authorization);
    
        Jws<Claims> jws = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(authorization);
        
        return "校验通过,你是:"+ jws.getBody().getSubject();
    
    }catch(Exception e){
    
        return "校验失败";
    
    }
}

token构造

header(签名算法).payload(数据).签名

  • 前两个部分都未加密
  • 所以token中不要放敏感数据

签名是根据前两部分根据一个密钥生成的

签名算法会生成一个签名值,会根据签名值是否相同判断token内容是否被篡改

[参考博客](Session 与 Token 的区别_love_onefly的博客-CSDN博客_session和token)

CSS

CSS是什么:即Cascading Style Sheets 级联(层叠)样式表,它描述了网页的表现与展示效果

选择器

  • type选择器 根据标签名进行匹配(元素选择器)
  • class选择器 根据元素的class属性进行匹配
  • id选择器 根据元素的id属性进行匹配

属性和值

  • background-color
  • display

在html中引入css文件

<link rel="stylesheet" href="style.css">

选择器

/*标签选择器*/
p {
    background-color: rgb(243,136,42);
}

/*类选择器*/
.c1{
    background-color: rgb(151,211,48);
}

/*id选择器*/
#p{
    background-color: cyan;
}

选择器优先级

同一标签被三种选择器作用,存在作用优先级

  • id选择器 > 类选择器 > 标签选择器

css样式大全:https://developer.mozilla.org/en-US/docs/Web/CSS/accent-color

布局

页面组成

  • header 标题信息
  • aside 菜单信息
  • main 主题信息
  • foot 版权备案信息等

div标签

容器标签,可以划分页面布局,容纳其它标签

template标签

结合js代码动态的加入到div中

JS

基础部分详细参考博客JavaScript

在js中函数也是一种对象

js中的默认值设置

function pagination(page = 1,size = 10){
    alert(page,size)
}

js中的匿名函数

(参数) => {
    //函数体
    return 结果;
}
  • 使用场景
    • 定义完后只调用一次,立即调用
    • 作为其它对象的方法

调用匿名函数

(function(a,b){
    return a + b;
})(1,2)
document.getElementById("p1").onclick = (function(){
   alert("鼠标单击事件"); 
});

箭头函数

无需写function

(参数) => {
    //函数体
    return 结果;
}
  • 如果只有一个参数 ()可以省略
  • 如果函数体内只有一行代码{}可以省略
document.getElementById("p1").onclick = () => alert("鼠标单击事件");

JS函数的作用域根据参数声明位置决定

函数定义时它的作用域已经确定好了,因此无论函数将来在哪里被调用,都能从它的作用域中找到需要的变量

闭包:闭包就是指函数能够访问自己的作用域中的变量

在java中也有类似的代码结构

  • lambda的参数捕获

函数接口

任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口

public interface TestObj {

     void accept(Integer x);

}

测试lambda

public class TestDemo {

    public static void main(String[] args) {

        a().accept(1);

    }

    public static TestObj a(){

        int y = 20;

        TestObj function = x -> System.out.println(x +","+y);

        return function;
    }

}

let、var与作用域

  • 如果函数外层引用的是let变量,那么外层普通的{}(比如if的花括号)也会作为作用域边界,最外层的let也占一个script作用域

  • 如果函数外层引用的是var变量,外层普通的{}不会视为边界

如果var变量出现了重名,则都会被视为同一作用域里的变量

var e = 10;
if(true){
    /*这里相当于重新赋值*/
    var e = 20;
    alert(e);
}
alert(e);
  • let则可以用花括号作为作用域分界

Array

语法

let arr [1,2,3];

遍历数组

for(let i = 0;i < arr.length; i++){
    alert(arr[i]);
}

API

  • push、shift、splice
//数组尾部添加数据
arr.push(4)
//头部移除一个元素
arr.shift()
//指定位置删除元素
arr.splice(2)
  • join
let arr = ['a','b','c']
//默认用逗号将元素连成一个字符串,也可以指定分隔符
arr.join();
  • map、filter、forEach
function a(i){ //代表新旧元素间的变换规则
    return i * 10;
}

arr.map(a);

高阶函数:map、filter、forEach

回调函数:作为参数传入的函数

JS对象

let obj = {
    _属性名:值
    方法名: 函数,
    get 属性名() {},
    set 属性名(新值){}
}

JS对象创建示例:

let obj = {
    _name: null, /*_开头类似于Java中的私有成员变量,实际上没有私有概念,直接访问_name不走get方法*/
    get name(){
        return this._name;    
    },
    set name(name){
        this._name = name;
    }
}

调用get,set方法

//默认执行了对象的set方法
obj.name = "Tom";
//默认执行了对象的get方法
alert(obj.name);

JS对象特色

属性增删

对比下Java中的Object

  • Java的Object是以类作为模板来创建,对象不能脱离类模板的范围,一个对象的属性,能用的方法都是确定好的
  • Js的对象,不需要什么模板,它的属性和方法可以随时加减
let obj = {name:"tom"};

obj.age = 18;

delete obj.age;

obj.method = function(){
    alert("对象的方法");
}

添加get,set

let obj = {_name:null};

Object.defineProperty(obj,"name",{
    get(){
        return this._name;
    },
    set(name){
        this._name = name;
    }
});

js中this的两种用法

let obj = {
    name:"tom",
    friends:["link","jack","tony"],
    play(){
        this.friends.forEach(e => {
            console.log(this.name + "与" + e + "在玩耍");
        })
    }
}
  • this.name所在的函数是箭头函数,因此this要看它外层的play函数,play又是obj的方法,因此this代表obj对象
tom与link在玩耍
tom与jack在玩耍
tom与tony在玩耍

不用箭头函数的做法

let obj = {
    name:"tom",
    friends:["link","jack","tony"],
    play(){
        let me = this;
        this.friends.forEach(function(e){
            console.log(this.name + "与" + e + "在玩耍");
        })
    }
}

JS继承

js采用原型继承方式,继承发生在对象之间

  • 对象中的_proto_属性引用了父类对象(原型对象)

js对象都是根据原型链模式查找对象属性,没有原型的对象会有一个默认的原型Object

js以父对象为原型创建子对象

let son = Object.create(father);

特色:基于函数的原型继承

处于方便的原因,Js又提供了一种基于函数的原型继承

函数职责

1、负责创建子对象,给子对象提供属性、方法,功能上相当于构造方法

2、函数有个特殊的属性prototype,它就是函数创建子对象的父对象

注意:区别于_proto_,这个属性的作用就是为新对象提供原型,实际上函数本身是有自己的_proto属性,是函数对象的父对象

配合new关键字,创建子对象

function cons(f2){
    //创建子对象(this),给属性f2赋值
    this.f2 = f2;
    //给子对象赋值方法
    this.m2 = function(){
        alert("子方法");
    }
}

//cons.prototype就是父对象
cons.prototype.f1 = "父属性"
cons.prototype.m1 = function(){
    alert("父方法");
}

/*
    创建子对象,此时子对象的_proto_就是函数的prototype属性
*/
let son = new cons("子属性")

json字符串和js对象的转换

JSON.parse(json字符串);  //返回js对象
JSON.stringify(js对象); //返回json串

JS属于动态类型语言,值有类型,但变量没有类型,赋值给变量时,没要求

  • 动态语言虽然比较灵活,但是变量没有类型,后期维护会有困难

JS中的一些符号

js中的???.

需求:如果参数n没有传递或是null,给它一个”male”,使用??

function test(n){
    n = n ?? '男';
}

其实??的作用相当于在空参条件下的默认值

需求,需要访问一个对象的子属性,如果子属性在不存在的情况下就需要用到?.

此时当某个属性是nullish时,短路并返回undefined

/*在不知道city属性是否存在的情况下*/
function test(obj){
    console.log(obj.address?.city);
}

展开运算符...

let arr = [1,2,3];
//相当于test(arr[0],arr[1],arr[2])
test(...arr);

//用于复制数组
let arr2 = [...arr];

//用于复制对象
let obj = {name:"tom",age:18};

let obj2 = {...obj}

//用于合并,同时也能添加新元素
let arr3 = [...arr,5,...arr2];

//出现同名,则后面的会覆盖前面的
let obj3 = {...obj,...obj2}

解构赋值[]{}

let arr = [1,2,3];

let [a,b,c] = arr;  //结果a=1,b=2,c=3

//用于对象参数接收,属性名需要相同
let obj = {name:"tom",age:18}

test({name,age}){
    alert(name,age);
}
test(obj);

for in

主要用来遍历对象

let obj = {name:"tom",age:18}

//const n 代表遍历出来的对象属性名
for(const n in obj){
    alert(n);
    //如果要获取属性值需要用[]
    alert(obj[n]);
}

for of

主要用来遍历数组,也可以是其它可迭代对象,如Map,Set等

let arr = [1,2,3];

for(const i of arr){
    console.log(i);
}

let arr2 = [
    {name:"tom",age:18},
    {name:"link",age:24},
    {name:"jack",age:19}
]

//两种for of对象遍历
for(const obj of arr2){
    console.log(obj.name,obj.age);
}

for(const {name,age} of arr2){
    console.log(name,age);
}

JS判断对象是否为空

if(JSON.stringify(obj) === '{}'){
    //对象为空
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com

文章标题:前端入门

字数:3.5k

本文作者:Os467

发布时间:2022-09-08, 10:21:00

最后更新:2022-11-17, 19:24:24

原始链接:https://os467.github.io/2022/09/08/%E5%89%8D%E7%AB%AF%E5%85%A5%E9%97%A8/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

×

喜欢就点赞,疼爱就打赏