html模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UFT-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>
基础标签及其常用的属性
<html>万物之源
lang=""(en/zh-CH)语言,其实有很多种,常用en英语和zh-CH简中,好像en也可以写中文
之后会在<head>和<body>列举常用标签和该标签常用属性
<head>万恶之源
<title>标题,用过就懂了
<meta />我不理解
charget=""(UTF-8)字符集,一般用UTF-8万国码,yyds
<body>万字之源
<h1><h2>~~<h6>标题,会加粗并且其字体按照数字由大到小,不可以把它当做加粗的文本随便用,h4和<p>的字体大小相仿。
<p>段落,最经典的分段,默认段落与段落之间的间距比较大。
id=""将此段命名,常用于链接和CSS
align=""字の位置,比如"center"就是段落居中
<img />图片
src=""图片路径,这个必须要有
art=""替换文本,图片加载失败的时候显示的文字
title=""提示文本,鼠标移动到图片上显示的文字
width=""图片像素宽
height=""图片像素高
border=""图片像素边框(学了css后就用不上这东西了,没必要记)
<a>超链接,可以指向网站、文件以及用于本网站的快速导航
href=""指定的url地址(如果填写href="#"的话就是空的,点了没用,但是没这句话字不会显示成超链
接的样子)。填写href="#name"可快速导航到有id="name"属性的标题/段落中去,暂时没有试过有多个
标题/段落同时拥有id="name"属性的情况。(阻止链接跳转还可以用
href="javascript:void(0)"或"javacript:;"这样没有#的标志)
target=""(_self,_blank)默认为_self,指定链接页面的打开方式,-self是本窗口打开,_blank是新窗口打开
<br />换行
<hr />分隔线
<strong>或<b>加粗
<em>或<i>倾斜
<del>或<s>删除线
<ins>或<u>下划线
<div>分割,分区(独占一行)
<span>多个span可共占一行
<!--注释-->
表格、列表、表单
<table>表格
<tr>行
<thead>表格头部区域
<tbody>表格主体区域
<td>单元格
<th>表头单元格
border=""(1)边框
cellpadding=""边沿与内容之间的空白像素(默认1)
cellspacing=""单元格之间空白像素(默认2)
width=""表格宽度
heigh=""表格高
rowspawn=""跨行合并(较难理解),在最上侧
colspanw=""跨列合并(较难理解),在最左侧
<ul>无序列表
<ui>列表项
<li>前面带·的列表项
<ol>有序列表
<li>列表项
<dl>自定义列表
<dt>一级列表
<dd>二级列表
表单:
表单域(就是<form>标签)
表单控件:
<input />输入
<label>为input元素定义标注
for="id"指向<input />中的name="id"属性
type=""属性值
button password checkbox(多选) radio(单选)
file reset hidden submit image text(输入文本)
name=""规定input元素名称
value=""规定元素初始值
checked(咋用的忘了)刷新或首次加载优先被选中
maxlength=""可输入的最大字符长度
<select>下拉列表
<option>选项
selected="selected"默认选中
<textarea>文本域,用于定义多行文本输入,默认输入[<>中的内容</>]。
row=""
line=""
cols=""最大字符数
提示信息
特殊符号
就像c语言中的%需要在printf中以"%%"的形式打出,html也有一些字符需要特殊方式才能输出
空格
< <
> >
& &
¥ ¥
©(版权) ©
®(商标) ®
° °
± ±
× ×
÷ ÷
² ²
³ ³
HTML5
针对于以前的不足,增加了一些新的标签、表单、表单属性等,具有兼容性问题(IE9+)
H5基础
HTML5新增的语义化标签
<header>头部标签
<nav>导航标签
<article>内容标签
<section>定义文档某个区域
<aside>侧边栏标签
<footer>尾部标签
这种语义化标准主要针对搜索引擎,在页面中可以使用多次,在IE9中需要将它们
转换为块级元素,移动端更喜欢用这些标签
多媒体标签
<video>视频 可以用mp4(推荐)、WebM(不推荐)、ogg(不推荐)
常见属性:
src="url"地址
autoplay="autoplay"自动播放(部分浏览器如谷歌会禁用)|
muted="muted"静音播放(可以取消上述浏览器的禁用)
controls="controls"向用户显示播放控件(各浏览器不一样以后用JS做吧)
width|height宽高
loop="loop"循环播放
preload="auto"(预先加载视频)|"none"(不先加载) 如果有autoplay就忽略此属性
poster="img's url"加载等待的画面图片
想克服兼容问题用下面的写法
<video width="320" height="240" controls>
<source src="movie.ogg" type="video/ogg">
<source src="movie.mp4" type="video/mp4">
您的浏览器不支持video标签。
</video>
<audio>音频 可以用MP3(推荐)、ogg(不推荐)、wav(不推荐)
常见属性:
src="url"
autoplay="autolpay"(谷歌等浏览器会禁用)
controls="controls"
loop="loop"
muted="muted"音频静音(意义不明)
preload="auto"|"metadata"|"none"默认加载及如何被加载
input类型(新增表单)
使用方式:type="属性值"
"email"只能输入Email类型|"url"只能输入Email类型|"data"日期类型|"time"时间类型
"month"月|"week"周|"number"数字|"tel"手机号码|"search"搜索框|"color"颜色选择表单
会在提交时就判断输入内容是否合规
新增表单属性
required="required"不能为空、必填
placeholder="提示文本"表单的提示信息
可以通过以下方式修改提示信息字体颜色
input::placeholder {color: ;}
autofocus="autofoces"自动聚焦,页面加载完成后自动聚焦到指定表单
autocomplete="off/on"开始输入时,浏览器基于之前键入过的值,显示出在字段中填写的选项
默认已经打开,需要放在表单内,同时加上name属性,同时成功提交
multiple="multiple"可以多选文件提交
Canvas
Canvas属于H5,在低版本浏览器不兼容(IE9+)
<canvas width='500' height='500'>
您的浏览器不支持Canvas! //支持canvas的浏览器看不到提示内容
</canvas>
canvas属于行内元素,在设置padding、margin时记得转换
基本画笔操作
画一条直线的步骤:
1.获取画布
2.获取画布的上下文
3.开始一条路径
4.确定起始点
5.确定结束点
6.着色
7.结束路径
var canvas = document.get管你咋get('canvas');
var c = canvas.getContext('2d'); 申明2d绘图,但事实上只有2d
c.beginPath();开启一条路径
c.moveTo(100,100);起始点
c.lineTo(200,200);结束点
c.strokeStyle = 'green' | rgbc(,,);
c.lineWidth = 5; 决定画笔粗细,这个在画圆等东西的时候也会用
c.stroke();上色
c.closePath();关闭路径
记得封装呀awa
c.fillRect(x左上角,y左上角,width像素宽,height像素高)
用fillStyle属性来设置用于填充绘图的颜色、渐变或模式
c.strokeRect(x,y,width,height);绘制空心区域
c.clearRect(x,y,width,height);清除画布
c.arc(x,y,radius,startAngle,endAngle,couterclockwise);画圆
x,y描述圆心坐标,radius描述弧的圆形半径
startAngle,endAngle沿着圆指定弧的开始点和结束点的一个角度,这个角度用弧度衡量
沿着X轴正半轴(三点钟方向)的角度为0,角度沿着逆时针方向增加而增加
可以用到Math.PI
couterclockwise 弧沿着圆周的逆时针方向(TRUE)还是顺时针方向(FALSE)遍历
c.fillStyle = (color); c.fill(); 填充
function a(color) {
c.strokeStyle = color || '#000'; //可以有效解决不传参问题
}
CSS
选择器
基础选择器
p,h1,div等 {}标签选择器,可以用“,”选择多样,称为并集选择器,习惯竖着写
.name {}类选择器
在标签中使用 class="name" 调用
#name {}id选择器,只能调用一次
在标签中使用 id="name"调用
* {}通配符选择器,选取所有
复合选择器
ul li {}只选择无序列表中的li而不选择有序列表(ol)中的li
.nav ul li {}只选择含class="nav"属性的标签中ul中的li
子元素选择器
元素1>元素2 {}只选择元素2是元素1儿子的时候
链接伪类选择器
a:link {}选择所有未被访问的标签
a:visited {}选择所有被访问过的标签
a:hover {}选择鼠标位于指针上的标签(最常用)
a:active {}选择鼠标按下未弹起的标签
为确保生效,请按照以上顺序声明
:focus伪类选择器
input:focus {}用于选取获得焦点的表单元素
文本
/*注释*/
字体(font)属性
font-family:"";字体
微软雅黑 Microsoft Yahei 写中文英文都行
ps:可以用,隔开多个字体(为了兼容,优先显示电脑安装了最靠左的字体)
font-size: 20px;字体大小(像素)
font-weight: normal;
nomal==400正常,默认
bold==700粗体
bolder特粗体
lighter细体
当然填数字是没问题的,100~900不要单位,实际开发中提倡使用数字
font-style: normal;
normal默认
italic斜体
事实上我们很少给文字加斜体,反而要让倾斜标签<em><i>改为不倾斜
font复合属性:
font: font-style font-weight font-size/line-height font-family;
使用方法: font:italic 700 16px 'Microsoft yahei'
必须保留font-size和font-family属性且保证顺序,否则不起作用
文本属性:
color: ;文本颜色
可以填写英文,rgb(,,)调色,#十六进制调色
text-align: ;水平对齐
left默认、right、center
text-decoration: ;
none默认,最常用,可用于超链接的下划线删除
underline下划线
overline上划线(意义不明)
line-through删除线(事实上不常用)
text-indent: ;文本缩进(一个char字符1em(相对文字大小,用px也行)),甚至可以使负数
line-hight: ;行高,行间距。文本间距包括上边距、下边距、文本高度。
上边距=下边距=(行高-文本高度)/2
转换成块级元素时,line-hight=hight时可实现垂直居中效果(想想原理)
引入方式
行内样式表(行内式):权重最高,会被同行追着打
此时style作为一种属性放到标签里就行,举例:
<div style="color=red;"></div>
内部样式表(嵌入式):优先级比链接式的高
在<head>中:
<style></style>
外部样式表(链接式):
外部写个.css文件,<style>标签就不用写了
引入的时候用<link rel="stylesheet" href="css文件地址"></link>
元素显式模式 display
块级元素:div {}
独占一行
可以控制高度、宽度、内外边距
宽度默认是父级宽度的100%
是一个容器/盒子,里面可以装放行内或者块级元素
文字类的元素内不能使用块级元素
行内元素:<a><span><b><em><i><del>...
相邻元素在一行上,一行可显示多个
直接设置宽和高是无效的
默认宽度是本身内容的宽度
行内元素只能容纳文本和其它行内元素
链接里不能再放链接
特殊情况下<a>里可以放块级元素
行内块元素:<img /><input /><td>(单元格) (未被正式命名)
和相邻行内元素(行内块)在一行上,但是它们中间会有空白缝隙一行可以显示多个
默认宽度就是本身宽度(行内元素特点)
高度,行高、外边距和内边距都可以控制(块级元素特点)
元素显示模式の转换:增加<a>的触发范围
display: block; 转换成块内元素(使用最多)
display: inline; 转换成行内元素
display: inline-block; 转换成行内块元素
CSS背景 background
background
background-color: transparent|color;(默认transparent透明)
background-image: none|url(填地址不要加引号);
background-repeat: repeat|no-repeat|repeat-x|repeat-y;背景平铺
背景图片会压住背景颜色
background-position: [x] [y];
可以放使用方位名词或精确单位
方位名词: top|center|bottom & left|center|right 可以省略一个center
精确单位:百分数|浮点数与单位标识符,只写一个值默认为 x center
可以混合使用,除了纯方位名词需遵守 x y 的顺序
background-attachment: ;(scroll滚动|fixed固定)背景附着
背景属性复合:
background: 背景颜色 地址 背景平铺 图像滚动 图像位置;
举例:
background: black url(image.jpg) no-repeat fixed center top;
background: rgba(r,g,b,alpha取个0~1浮点数);背景色半透明,0.3=.3
CSS特性
层叠性
像python一样,相同权重时,后执行的语句会覆盖前面的语句
继承性
子代可以继承父代的样式
font: 12px/24px "Microsoft YaHei";
行高为24px,如果文字大小未设定,则为12px
font: 12px/1.5 "Microsoft YaHei";
这个1.5就是当前文字大小(font-size)的1.5倍
优先级
选择器权重:(一把来说,范围越小,权重越大)
继承/* 0,0,0,0
元素选择器 0,0,0,1
(伪)类选择器 0,0,1,0
ID选择器 0,1,0,0
行内样式 style="" 1,0,0,0
!important 重要的 无穷大
使用方法举例:
color: pink!important;
盒子模型
页面布局三大核心:盒子模型、浮动、定位
border边框
border-width: px;定义边框粗细
border-style: ;边框的样式
none|hidden|dotted点线|dashed虚线|solid实线
double双线|groove|ridge|inset|outset
border-color: ;边框颜色
border简写:
border: 1px solid red;没有顺序要求
border-top只定义上边框
border-bottom只定义下边框
border-left左边框
border-right右边框
border-collepse:collepse;
表示相邻边框合并到一起,防止边框合并变粗
边框会影响盒子实际大小
padding内边距
padding-[方位]: 20px;[方位]=left|right|top|bottom
padding简写
padding: 5px;上下左右都有5px
padding: 5px 10px;上下5px,左右10px
padding: 5px 10px 20px;上5px,左右10px,下20px
padding: 5px 10px 20px 30px;上5右10下20左30,顺时针
内边距也会影响盒子实际大小,
但如果盒子本身没有指定width/height属性,此时padding不会撑开盒子大小
margin外边距
margin-[方位]: 20px;[方位]=left|right|top|bottom
margin简写与padding简写规则完全相同
外边距可以让块级盒子水平居中,但是必须满足:
①:盒子必须指定宽度width
②:左右外边距设定为aotu
margin-left= aotu;margin-right= aoto;
margin= aotu;
margin=0 aotu;
这种方法只适用于块级元素,行内元素及行内块元素请对其父元素使用:
text-align: center;
注意上下相邻块元素之间会出现垂直外边距的合并问题,尽量只给一个盒子添加margin值
对于两个嵌套的块级元素,父子同时拥有上外边距,会出现垂直外边距塌陷问题
此时可以为父元素定义上边框|上内边距|添加overflow: hidden;
清除内外边距
网页元素很多都带有默认的内外边距,而且不同浏览器默认的也不一致,所以可以提前清除内外边距:
* {
padding: 0;
margin: 0;
}
行内元素尽量只设置左右的内外边距
浮动 float
浮动最典型的应用:可以让多个块级元素一行内排列显示。
网页布局第一准则:多个块级元素纵向排列找标准流,横向排列找浮动。
网页布局第二准则:先设置盒子大小,之后设置盒子的位置。
float属性用于创建浮动框,将其移动到一遍,直到左或右边缘触及包含块或另一个浮动框的边缘
语法: 选择器 {float:属性值;}
浮动特性:
1.浮动元素会脱离标准流
2.浮动的盒子不再保留原先的位置
3.如果多个盒子都设置了浮动,则他们会按照属性值一行内显示并顶端对齐排列
4.浮动元素会具有行内块元素的特性
如果块级盒子没有设置宽度,默认宽度和父级一样宽,但是添加浮动后,它的大小根据内容来决定
浮动的盒子中间是没有缝隙的,是紧挨着一起的
行内元素同理
为了约束浮动元素位置,我们网页布局一般采取的策略是:
先用标准流的父元素排列上下位置,之后内部子元素采取浮动排列左右位置,复合网页布局第一准则
常见网页布局:
top banner box footer
浮动和标准流的父盒子搭配;
一个盒子浮动了,理论上其余的兄弟元素也要浮动。
清除浮动:
由于浮动元素不再占用原文档流的位置,所以它会对后面的元素排版产生影响
使用时机:父元素没高度,子元素浮动,影响布局
语法:选择器 {clear:属性值;}
属性值:left清除左边浮动的影响,right同理,both同理 基本只用both
方法1:额外标签法(隔墙法)
W3C推荐做法在浮动元素末尾添加一个空的块级标签如
<div style="clear:both"></div>
特点:通俗易懂,但缺乏结构感
方法2:父级添加overflow属性
属性值为hidden(常用)、auto、scroll,如:
.父元素类 {overflow: hidden;}
无法显示溢出部分
方法3:父级添加after属性
额外标签法的升级版(只是原理相同)
在css中直接加入如下代码:
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix { /*IE6、7专有*/
*zoom: 1;
}
然后给父元素的class加上clearfix就行,当库用不过脑子
特点:没有增加标签,结构更简单,可以当c类语言的库用,百度淘宝网易等都在用
方法4:父级添加双伪元素
基本原理同上,代码更多
.clearfix:before,.clearfix:after {
content:"";
display:table;
}
.clearfix:after {
clear:both;
}
.clearfix {
*zoom:1;
}
特点:代码更简洁,小米腾讯等都在用
定位 position
定位组成
定位 = 定位模式 + 边偏移
定位模式用于指定一个元素在文档中的定位方式,它通过CSS的position属性来设置,其值可分为四个:
static 静态定位
relative 相对定位
absolute 绝对定位
fixed 固定定位
stickt 粘性定位
边偏移则决定了该元素的最终位置,其属性也有四个:
top 顶端偏移量
bottom 底部偏移量
left 左侧偏移量
right 右侧偏移量
使用示例:top:80px,表示相对于父元素上边线的距离
静态定位static(默认)
position: static;
按照标准流特性摆放位置,它没有边偏移,在布局中很少使用
相对定位relative(重要)
position: relative;
top: 100px;
left: 50px;
以原来的位置为标准向下移动100px,向左移动50px
仍是标准流,保留原来位置(原来的位置还是被占住的)
因此,相对定位并没有脱标,它最典型性的应用是给绝对定位当爹的。。。(视频原话)
绝对定位absolute(重要)
position: absolute;
如果没有祖先元素或祖先元素未定位,则以浏览器为准定位(Document文档)
否则以最近一级祖先元素为准定位
不再拥有原来的位置(脱标)
口诀:子绝父相 指子元素为绝对定位则父元素需要是绝对定位
固定定位fixed(重要)
position: fixed;
固定于浏览器可视区的位置,可以在浏览器页面滚动式元素的位置不会改变。
靠近版心的定位法:让固定定位的盒子left: 50%;再margin-left: 版心宽度的一半距离。
粘性定位sticky(要求了解,但真的很神奇,可是兼容太差,可以用js做)
position: sticky;
可以认为是相对定位relative和固定定位fixed的混合
以浏览器的可视窗口为参照点移动元素
占有原先的位置
必须添加top、left、right、bottom其中一个才有效
定位叠放次序:z-index
选择器 { z-index: 1; }
数值可以是正整数、负整数、0,默认是auto,数值越大,盒子越靠上
不可以加单位,只有定位的盒子才会有z-index属性
注意点:
绝对定位的盒子不可以用margin:auto;水平居中,可以用以下方法:
left: 50%; margin-left: -宽度的一半; 垂直居中同理
绝对定位和固定定位也和浮动类似
1.行内元素添加绝对或者固定定位,可以直接设置高度和宽度
2.块级元素添加绝对或者固定定位,如果不给宽高,默认为内容的大小
3.脱标的盒子不会发生外边距塌陷
4.绝对定位/固定定位会完全压住盒子
浮动的元素不会压住下方标准流的文字图片,定位会压住下方标准流的所有内容
(因为浮动原本是用来做文字环绕图片用的)
显示与隐藏 display
display显示隐藏
display属性用于设置一个元素如何显示
常用语句 display: block|inline|none;
display: none;隐藏对象
display: block;除了设置为块级元素以外还有显示元素的意思
display: none;不再占有原来的位置
visibility显示隐藏
visibility: inherit(默认)|visible|collapse(不常用)|hidden
隐藏元素后,仍占有原来位置
overflow溢出显示隐藏
overflow: visible(默认)|auto|hidden|scroll
visible: 不剪切内容也不添加滚动条
auto: 在需要时显示滚动条
hidden: 不显示超过对象尺寸的内容
如果有定位的盒子慎用,因为它会隐藏多余的部分
scroll: 总是显示滚动条
高级技巧
精灵图:为了有效减少服务器接收和发送请求的次数,提高页面的加载速度
核心原理:将网页中的一些小背景图像整合到一张大图中,这样服务器只需要一次请求就可以了
精灵图主要应用于小型背景图,用background-position移动背景图片位置
移动的位置就是这个目标图片的x和y坐标,注意坐标数值应用问题
使用精灵图的时候需要精确测量每个小背景图片的大小和位置
字体图标iconfont:为前端工程师提供一种方便高效的图标使用方式,展示的是图标,本质属于字体
icon下载网站:https://icomoon.io/(外国) https://www.iconfont.cn/(阿里)
下面是icomoon的使用方法:
把下载到的fonts文件夹放到根目录下,该解压解压
再在CSS样式中全局声明字体,代码在文件夹中的style.css里的前一部分
然后复制demo.html中的框框
用图标的时候在css里加上font-family: 'icomoon'即可
追加图标时把selection.json文件重新上传至网站,重新下载、解压就行
CSS三角:
当你让一个盒子的宽高都设置为0,但是加入了四个不同颜色边框后你就懂了
border: 10px solid transparent(透明);
border-你要哪个方向都行: 10px solid 颜色;
为了兼容问题考虑,建议把width,height,line-height,font-size全设置为0
放到一个大盒子里,用定位调整一下位置,就可以实现对话气泡的箭头效果
调整每一个边框的大小,可以调出各种各样的三角形(比如不等腰直角三角形)
更改界面样式:
改变鼠标样式:{cursor: 阿巴阿巴;}
属性值:default(默认)|pointer(小手)|move(移动)|text(文本I)|not-allowd(禁止符号)
取消表单轮廓: input,textarea{outline: none;}
防止表单域拖拽: textarea{resize: none;}
行内(块)元素垂直对齐:vertical-aligh: baseline|top|middle|bottom;
baseline默认,对齐于父元素基线 top把元素的顶端与行中最高元素的顶端对齐
middle把元素放置在父元素中部(最常用) bottom与行中最低的元素的顶端对齐
一般给图片、文本域等用,使图片与文字垂直居中
也可以用来消除图片低侧空白空隙(也可以将图片设置为块级元素来解决空隙问题但不推荐用)
溢出文字省略号代替:
单行溢出
1.先强行一行内显示文本white-space: nowrap;(默认normal自动换行)
2.超出部分隐藏overflow: hidden;
3.文字用省略号替代超出的部分text-overflow: ellipsis;
多行溢出(较大兼容问题,适用于webKit浏览器或移动端)
overflow: hidden; /*交给后端人员他们能做的更方便*/
text-overflow: ellipisis; /*为什么不直接复制呢*/
diplay: -webkit-box; /*限制在一个块元素显示的文本的行数*/
-webkit-line-clamp: 2; /*限制在一个块元素显示的文本的行数*/
-webkit-box-orient: vertical; /*设置或检索伸缩盒对象的子元素的排列方式*/
消除边框重叠的margin小技巧:margin-left: -1px;
被压住的盒子想要显示四个边框(尤其是hover的时候)提高层级即可
方法:添加相对定位,如果已经有了定位就用z-index
通用规范与杂项
list-style: none;去除无序列表li前面的项目符号(小圆点)
CSS属性书写顺序:
1.布局定位属性:display/position/float/clear/visibility/overflow
2.自身属性:width/height/margin/padding/border/background
3.文本属性:color/font/text-decoration/text-aligh/vertical-aligh/white-space/break-word
4.其他属性(CSS3):content/cursor/border-radius/box-shadow/text-shadow.....
网页布局总结
通过盒子模型,清楚知道大部分html标签是一个盒子
通过CSS浮动、定位可以让每个盒子排列成为网页
一个完整的网页,是标准流、浮动、定位一起完成布局的,每个都有自己的专门用法
1.标准流
可以让盒子上下排列或者左右排列,垂直的块级盒子显示就用标准流布局
2.浮动
可以让多个块级元素一行显示或者左右对齐盒子,多个块级盒子水平显示就用浮动布局
不要忘了浮动本来是做文字环绕效果的
3.定位
有层叠的概念(让多个盒子前后叠压显示),如果元素自由在某个盒子内移动就用定位布局
CSS初始化代码
* {margin: 0;padding: 0;}
em,i {font-style: normal;}
li {list-style:none;}
img {border: 0;vertical-align: middle;}
button {cursor: pointer;}
a {text-decoration: none;}
body{
-webkit-font-smoothing: antialiased; /*抗锯齿*/
background-color: #fff;
}
.clearfix:after {visibility: hidden;clear: both;display: block;content: ".";height: 0;}
.clearfix {*zoom: 1;}
CSS3
CSS3基础
具有兼容性问题(ie9+),移动端支持优于PC端,不断改进中,应用相对广泛
新增选择器:
属性选择器
E[att] {}选择具有att属性的E元素
E[att="val"] {}选择具有att属性且属性值为"val"的E元素
E[att^="val"] {}att属性值以val开头
E[att$="val"] {}att属性值以val结尾
E[att*="val"] {}att属性值含有val
结构伪类选择器:根据文档结构来选择元素,常用于根据父级选择器里面的子元素
E:first-child {}匹配父元素中的第一个子元素E
E:last-child {}匹配最后一个子元素E
E:nth-child(num) {}匹配第num个子元素E
会把所有的盒子都排成序号
num可以是数字,关键字(even偶数、odd奇数),甚至可以是公式
常见公式:2n偶数|2n+1奇数|5n(5,10,15...)|n+5从第5个开始|-n+5前5个(包括)
n为公式时,从0开始计算,第0个元素或者超出了的元素的个数会被忽略
E:first-of-type {}指定类型E的第一个
E:last-of-type {}指定类型E的最后一个
E:nth-of-type {}指定类型E的第n个
会把指定盒子都排成序号
伪元素选择器:可以利用CSS创建新标签元素,而不需要HTML标签,从而简化HTML结构
element::before {}在元素内部的前面插入内容
element::after {}在元素内部的后面插入内容
创建的元素属于行内元素,必须有content属性,和标签选择器一样权重为1
属性:content: '内容'; 这里面写的东西不用&;了,直接写就完事
盒子模型:box-sizing: content-box(默认)|border-box
box-sizing:content-box 盒子大小为width+padding+border
box-sizing:border-box 盒子大小为width
此时padding和border就不会撑大盒子了(除非padding+border>width)
CSS3过渡transition:
transition: 要过渡的属性 花费时间 运动曲线 何时开始;
属性: 如width、height、背景颜色、margin、padding等,也可以写all表示全部
花费时间: 单位为s,比如 .5s
运动曲线: 默认是ease , 可以省略
linear匀速 ease逐渐慢下来 ease-in加速
ease-out减速 ease-in-out先加速后减速
合适开始: 单位是s,可以设置延迟触发时间,省略的话默认为0s
要注意:写多个过渡属性的方法如下(不可以写两个transition属性!)
transition: width .5s ease 1s, height .5s ease 1s;
经常配合hover食用,transition不写在hover里(谁做过渡给谁加)
CSS3其它特性:
滤镜filter: filter: 函数();
例如filter: blur(5px); 模糊处理 数值越大越模糊
calc()函数:在声明CSS属性值时执行一些计算
width: calc(100%-80px);
css3进阶:transform & animation
transform:
transform: translate()
小盒子在大盒子中垂直居中
position: absolute;top: 50%;left: 50%;
transtorm: translate(-50%, -50%);
transform: rotate(10deg)
单位deg是角度
记住transform有先后顺序,移动和旋转的顺序很重要
transform: scale()
animation动画
@keyframes name {
0%{} //开始
70{} //结束
}
通过加入属性 animation: name 时间 渐进 循环与否;引入动画
steps()步长
可以增加多个动画,用逗号分隔
animation-play-state: paused;停止动画
transform:3D转换
近大远小,物体后遮挡不可见
x轴: 右边是正值,左边是负值
y轴: 下面是正值,上面是负值
z轴: 外面是正值,里面是负值
transform: translate3d(x,y,z)
translateZ单位一般使用精确像素(px)单位
transform: rotate3d(x,y,z,deg)
xyz表示旋转轴的矢量,表示你是否希望沿着该轴旋转
deg表示旋转的角度,单位为deg
实际开发中常用rotateX/Y/Z而不用简写
perspective: d; 透视,单位px
写在被观察元素的父盒子上面(并非一定要亲父,可以是重重祖父)
d:视距,距离人的眼睛到屏幕的距离(px)
z:指z轴,物体距离屏幕的距离,z轴越大(正值)我们看到的物体就越大
透视我们也称为视距,指人的眼睛到屏幕的距离
距离视觉点越近的在电脑平面成像越大,越远成像越小
transfrom-style: flat;(默认) 3D呈现
控制子元素是否开启三维立体环境
transform-style: preserve-3d;子元素开启立体空间
代码写给父级,但是影响的是子盒子
移动端
视口、二倍图
视口:就是浏览器显示页面内容的屏幕区域
视口分类
layout viewport布局视口
一般移动设备的浏览器都默认设置了一个布局视口,用于解决早起PC端页面在手机上显示的问题
IOS、Android基本都将这个视口分辨率设置为980px
visual viewport视觉视口
指用户正在看到的网站的区域
可以通过缩放去操作视觉视口,但不会影响布局视口,布局视口仍保持原来的宽度
ideal viewport理想视口
为了使网站在移动端有最理想的浏览和阅读宽度而设定
需要手动添写meta视口标签通知浏览器操作
meta视口标签的主要目的:布局视口的宽度应该与理想视口的宽度一致
meta视口标签
<meta name="viewport" content="width=device-width, user-scalable=no,
initial-scale=1.0, maxinum-scale=1.0, mininum-scale=1.0">
width 宽度设置的是viewport宽度,可以设置device-width特殊值
initial-scale 初始缩放比,大于0的数字
maximum-scale 最大缩放比,大于0的数字
minimun-scale 最小缩放比,大于0的数字
user-scalable 用户是否可以缩放,yes或no(1或0)
二倍图:我们准备的图片比我们实际需要的大小大2倍
物理像素&物理像素比
物理像素指的是屏幕显示的最小颗粒,是物理真是存在的。出厂时就设置好了
开发时1px不一定等于1个物理像素(PC端一一对应而移动端不尽相同)
一个px能显示的物理像素点的个数,称为物理像素比或屏幕像素比
background-size: 背景图片宽度 背景图片高度; 属性规定背景图像的尺寸
background-size: cover; 会使图片缩放到填满整个父盒子
background-size: contain; 把图像扩展到最大完全适应内容区域(等比例最适合最大)
flex布局
对父盒子:
diplay:flex;
flex-direction: row; 设置主轴方向
row|row-reverse|colomn|column-reverse
justify-content: flex-start; 设置主轴上子元素排列方式
flex-start|flex-end|center|space-around|space-between
flex-warp: nowrap|wrap; 设置主轴是否换行
align-items: flex-start; 设置侧轴上的子元素排列方式(单行)
flex-start|flex-end|center(垂直居中)|stretch(拉伸,子盒子此时不要高度)
aligh-content: flex-start; 设置侧轴上的子元素排列方式(多行)
flex-start|flex-end|center|space-around|space-between|stretch
flex-flow: ;是flex-direction和flex-wrap的复合属性
对子盒子:
flex: <number>; 默认为0
aligh-self: ;控制子项自己在侧轴的排列方式
order: ;设置弹性盒对象元素的顺序
JavaScript
基础语法
引入方式
行内样式表(行内式):权重最高,(会被同行追着打)
作为一种属性放到标签里就行,举例:
onclick= "alert('awa')"
在Html中使用双引号,在js中使用单引号
内部样式表(嵌入式):优先级比链接式的高
在<head>中:
<script></script>
外部样式表(链接式):
外部写个.js文件:
<script src=".js文件路径"></script>
中间不可以放代码
基本语句:
prompt(msg);让用户输入,msg为提示词,返回输入的字符串,注意是字符串
alert(msg);弹出内容为msg的警示框
console.log(msg);在console调试界面中输出,给同行和自己看的
var 函数名; 跟python一样不需要管类型
typeof 函数名 返回数值类型
数字类型
0+数字 表示八进制
0x+数字 表示十六进制 比如0xFFFFFF
(Number型数字).toString(16); 可以将数字转成16进制
来个随机16进制: (Math.random()*0xFFFFFF).toString(16);
字符串变量
str.lenth返回字符串的长度,这里不用其它语言写函数常用的()
字符串的拼接:字符串+不管什么型甚至可以是undefined、null=新的连在一起的字符串
布尔类型
true和false在加减法中可视作1/0
数据类型转换:
其它类型变量转成字符串的方法:
| 方式 | 说明 | 案例 |
|---|---|---|
| toString() | 转成字符串 | var num=1;alert(num.toString()); |
| String()强制转换 | 转成字符串 | var num=1;alert(String(num)); |
| 拼接字符串 | 见上文 | alert(num+"字符串"); |
其他类型(主要是字符串)转数字型:
parseInt(msg); 向下取整,忽略单位
parseFloat(msg); 取浮点数
Number(msg) 强制转换
数字字符串 - 0 强制转换2
原理是遇到算术运算时会自动转换成数字,用+的时候要注意会出问题
转换成bool型:
Boolean();代表空、否定的会转换为false,其它的都是true
比如 '',0,NaN,null,undefined == false
运算符
算数运算符:
+-*/%
浮点数直接参与运算会有精度不确定问题
不可以拿浮点数直接做比较
a++,++a
比较运算符:
< , > , <= , >= , !=
==判等号(会转型)
===全等(要求值和数据类型都一致)
逻辑运算符:
&& , || , !
JavaScript一样存在逻辑短路现象
赋值运算符:
= , += , -= , *= , /= , %=
流程控制分支结构 与 循环
流程控制:
if(条件表达式) {}
else {}
三目运算符:条件表达式 ? 表达式1 : 表达式2;
switch(表达式) {
case value:
执行语句;
break;
default:
执行语句;
break;
} //注意表达式要与value全等而不是相等
循环:
for(var i =1;i<=100;i++) {}
while() {}
do {}whlie() //while()没有';'
continue;
break;
数组与函数
数组:
var arr = new Array(); //创建一个空的数组
var arr = []; //创建一个空的数组
var arr = [1,2,'awa',true];
console.log(arr);可以在控制台直接输出数组
数组索引号(下标)还是从零开始
遇到未定义的会返回undefined
数组名.length //没有括号,返回数组长度
要注意,这个length是可修改的,可以通过增加length长度达到添加元素的目的
如果给数组名直接赋值,会使其直接变成普通变量
arr.push(x); 在数组末尾添加新项目,返回新长度
arr.unshift(x); 在数组开头添加新项目,返回新长度
arr.pop(); 移除数组的最后的元素,并返回移除的元素
arr.shift(); 移除数组的第一个元素,并返回移除的元素
arr.splice(a,b,...); 从arr[a]开始删除b个,并在arr[a]的位置插入...(比如c,d,e,f)
函数:
声明函数:
function 函数名(放形参,甚至不需要用var定义,直接写形参名就行了) {}
var 变量名 = function() {} 匿名函数,不会预解析
return 返回的结果;如果没有return返回undefined
arguments伪数组,在函数中存储了所有传进来的实参,用这个就可以不用形参啦
可以在函数内声明函数
作用域与预解析
全局作用域 局部作用域
全局变量 局部变量
注意,在函数内部(局部作用域)没有声明类型的变量是全局变量
全局变量只有在浏览器关闭时才会销毁
内部函数王文外部函数的变量,采取的是链式查找的方式来决定哪个值,这种结构称为作用域链
预解析:
运行js: 预解析 、 代码执行
预解析js引擎会把js里所有的var还有function提升到当前作用域的最前面
对象
var obj = {};创建了一个空的对象
var obj = new Object();
创建object对象
var obj = {
uname: 'Cloyir',
age: 18,
sayHi: function(){
console.log('hi~');
}
};
里面的属性或者方法采取键值对的形式(键 属性名 : 值 属性值)
多个属性或方法用逗号隔开
方法冒号后面跟的是一个匿名函数
调用对象:
obj.uname对象名.属性名
obj['age']对象名['属性名']
obj.sayHi();对象名.方法名()
为未命名的属性或方法赋值会创建出新的属性和方法
构造函数对象
function 构造函数名(形参) {
this.属性名 = ;
}
var a = new 构造函数名(实参);
//构造函数名一般首字母大写,构造函数不用return(废话)
遍历对象内元素:
for(var k in obj){}
obj[k]即为元素的值(k为元素的属性名)
内置对象: MDN官网
JS对象分为三种:自定义对象、内置对象、浏览器对象(参考c语言头文件)
查阅MDN/W3C即可,不记了~
常用的:
Math.random();取[0,1)之间的浮点数
取两个数之间的随机整数并包含这两个整数
function getRandom(min,max){return Math.floor(Math.random()*(max-min+1))+min;}
浏览器DOM、BOM操作
基础知识定义
API 应用程序编程接口
一组预先定义的函数,提供访问一组例程的能力
Web API 提供一套操作 浏览器功能(BOM)和页面元素(DOM)的API
比如说alert("弹出")
DOM
DOM文档对象类型,是W3C组织推荐的处理可扩展标记语言的标准编程接口
W3C已经定义了一系列DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式
DOM树:一个一面就是一个文档(document)、所有标签都是元素(element)、所有内容都是节点(node)
获取元素
根据类名
document.getElementById()根据ID获取
var 变量名 = document.getElementById('id名');
返回一个匹配到ID的DOM element对象(object),没找到则返回NULL
(可以用console.dir(变量)查看object查看详细数据)
根据元素
document.getElementsByTagName()根据标签名获取
var 变量名 = document.getElementsByTagName('标签名比如p,h1等');
返回object集合,伪数组
var ol document.getElementsByTagName('ol');
console.log(ol[0].getElementsBuTagName("li"));
document.getElmentsByClassName()根据类名获取返回元素对象集合
var 变量名 = document.getElementsByClassName('nav');
根据选择器
document.querySelector('选择器');
根据指定选择器返回第一个元素对象
var firstbox = document.querySelector('.box');
document.querySelectorAll('选择器')返回指定选择器的所有元素对象集合(伪数组)
获取body元素 var a = document.body;
获取html元素 var a = document.documentElement;
事件 三要素:事件源、事件类型、事件处理程序
事件源: 事件被触发的对象(var a = document.getElementById('btn'))
事件类型: 如何触发 什么事件
事件处理程序: 通过一个函数赋值的方式完成
btn.onclick = function(){alert('awa');}
事件处理程序
div.innerText = 字符串(可函数可值);
更改文字内容,不识别html标签 非标准 去除空格和换行
div.innerHTML = '';
支持标签 保留空格和换行
可以做出 node.innerHTML = node2.value + "<a href="#"></a>"的操作
修改: object对象变量名.属性=值
input.value = 'awa';
this.disabled = true; //this指向的是事件函数的调用者
a.style.display = 'none';
事件: onclick鼠标点击
onfocus获得焦点
onblur失去焦点
onmouseover鼠标经过
onmouseout鼠标离开
this.style 行内样式操作
this.className='';类名样式操作,会直接更改原先类名
操作元素
操作元素内容:innerText、innerHTML
操作常见元素属性:src、href、title、alt
操作表单元素属性:type、value、disabled
操作元素样式属性:element.style、.clssName
自定义属性
获取属性
e.属性 获取属性内置值
e.getAttribute('属性') 可以获得自定义属性
设置与移除
e.setAttribute('属性','值')
e.removeAttribute('属性')
H5自定义属性规范
规定自定义属性以"data-"开头比如"data-index"
以data-开头的自定义属性H5新增了e.dataset.index或者e.dataset['index']
的获取方式(ie11+),此时使用驼峰命名法
比如index-list-name → e.dataset['listName']
节点操作 利用父子兄节点关系获取元素
基本属性:nodeType节点类型、nodeName(节点名称)、nodeValue(节点值)
父级节点: node.parentNode 找不到返回null
标准子节点(不提倡): node.childNodes 包含元素节点、文本节点等所有子节点的集合
非标准子节点(常用): node.children 子节点中元素节点的集合
其它子节点: node.firstChild、node.lastChild 会返回文本节点所以不提倡
node.firstElementChild 返回子节点第一个元素节点,没有则返回null (IE9+)
想避免兼容性问题使用 node.children[0] 即可
node.lastElementChild 同理 (IE9+)
同上,一般使用 node.children[node.children.length -1])
兄弟节点
node.nextSibling 会得到下一个包括文本节点的节点
node.previousSibling 同上,上一个
node.nextElementSibling 下一个元素节点,没有则返回null(IE9+)
node.previousElementSibling 上一个元素节点,没有则返回null(IE9+)
解决方法:封装函数:
function getNextElementSibling(element) {
var el = element;
while(el = el.nextSibling)if(el.nodeType === 1)return el;//自行补括号
return null;
}
添加节点 先创建后添加
document.createElement('tagName') 创建由tagName指定的HTML元素(动态创建元素节点)
node.appendChild(child) 将一个节点添加到指定父节点的子节点列表末尾
(类似css中after伪元素)node是父级,child是要添加的节点
node.insertBefore(child,指定元素) 添加到指定元素前
如 father.insertBefore(newli,father.children[0]);
删除节点
node.removeChild(child) 从DOM中删除一个子节点,返回删除的节点
这里删干净了再删会报错,建议判断一下长度为0时禁用删除
复制节点 复制了别忘了添加awa
node.cloneNode(bool)
括号参数为空或者为false为浅拷贝,只克隆节点本身,不克隆里面的子节点(包括文本)
如果为true,则为深拷贝,懂的都懂
本地存储
本地存储特性
1.数据存储在用户浏览器中
2.设置、读取方便、甚至页面刷新不丢失数据
3.容量较大,sessionStorage约5M、localStorage约20M
4.只能存储字符串,可将对象JSON.stringify()编码后存储
sessionStorage
1.生命周期为关闭浏览器窗口
2.在同一个窗口(页面)下数据可以共享
3.以键值对的形式存储使用 存储在Application→Storage→Session Storage中(F12)
sessionStorage.setItem(key,value) 存储|修改 //key为键值,里面放字符串
sessionStorage.getItem(key) 获取,返回字符串value,可用if(...)判断是否得到
sessionStorage.removeItem(key) 删除
sessionStorage.clear() 删除所有数据(少用,删多了会被打)
localStorage
1.生命周期永久生效(直到清理浏览器缓存),除非手动删除 否则关闭页面也会存在
2.可以多窗口(页面)共享(同一浏览器)
3.以键值对的形式存储使用
4.可以以缓存的形式存储在生成的app里!!!
localStorage.setItem(key,value)
localStorage.getItem(key) 可用if(...)判断是否得到
localStorage.removeItem(key)
localStorage.clear()
计时
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
setInterval(code,millisec[,"lang"])
code 必需。要调用的函数或要执行的代码的字符串。
millisec 必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。
返回一个可以传递给 Window.clearInterval() 从而取消对 code 的周期性执行的id值。
clearInterval() 方法可取消由 setInterval() 设置的 timeout。
clearInterval() 方法的参数必须是由 setInterval() 返回的 ID 值。
setTimeout(code,millisec);
只执行 code 一次。如果要多次调用,请使用 setInterval()
或者让 code 自身再次调用setTimeout()
clearTimeout() 方法可取消由 setTimeout() 方法设置的 timeout。
clearTimeout(id_of_settimeout)
ES plus
前置知识:
- JavaScript基本语法(ES5)
- AJAX与NodeJS
ES6基础
let 在块级作用域里声明变量
解构赋值:ES6中允许按照一定模式从数组和对象中提取值,对变量进行复制
const arr = [1,2,3,4];
let [num1,num2,num3,num4] = arr;
试试console.log(num1,num2,num3,num4);
const obj = {a = 1,b = 2,c = function(){consoloe.log('c')}}
let {a,b,c} = obj;
试试 cosole.log(a,b,c);c();
允许function f({a,b,c}){return a+b+c};f({a:1,b:2,c=3});
允许使用const声明常量,必须赋初始值,命名规范为全字母大写
但const存数组的时候因为只存了地址所以你还是可以修改数组中的值
`string` 模板字符串:可以将反引号作为字符串的声明方式,效果类似单双引号'',""
内容中可以出现换行符
可以快速拼接字符串:
let a = '123';let b = `${a}456`;
格式如上,`${你要拼接的字符串}....`
允许在对象中快速声明函数:
let a = {f(){}}; 而原来的写法是 let a={f:function(){}}
=>声明函数:
let f = () => {} 效果类似let f=function(){}
这样声明的函数的this是静态的,始终指向声明函数时所在作用域下的this的值
不能作为构造实例化对象(不可用于声明对象)
不可以使用arguments变量
当形参有且只有一个的时候可以省略小括号,
而代码体只有一条语句的时候可以省略花括号,此时return也必须要省略,返回语句执行结果
let f = n => n;等价于let f=(n)=>{return n;}
给函数参数赋值初始值
1.形参初始值
function add(a,b,c=0){return a+b+c}
此时不传c的值的话,c会被赋值为0而不是undefined
与解构赋值向结合:function f({a=1,b,c}){return a+b+c;}
此时调用f时传入的对象没有a时会初始化为1
...扩展运算符
「...」能将「数组」转换为逗号分隔的「参数序列」,可用于函数传参,将数组拆成多个数据
你甚至可以let arr = [...arr1,...arr2]将两个数组合并!
你甚至还可以把伪数组转成真数组!let d = [...document.querySelectorAll('div')]
Symbol类型 js的第七个原始数据类型
Symbol的值是唯一的,用来解决命名冲突的问题,不可参与任何运算,与任何可比对对象都不相等
Symbol定义的对象属性不能使用for in循环遍历,但是可以用Reflct.ownKeys来获取所有键名
Iterator迭代器
一种接口,为各种不同的数据结构提供统一的访问机制
任何数据机构只要部署Iterator接口,就可以完成遍历操作
1)ES6创造了一种新的遍历命令for...of循环,Iterator接口主要为其服务
2)原生具备Iterator接口的数据(可用for...of遍历)
Array|Arguments|Set|Map|String|TypedArray|NodeList
for(let v of arr){} v为键值(for...in时是键名)
3)工作原理
创建一个指针对象,指向当前数据结构的起始位置
第一次调用对象的next方法,指针自动指向数据结构的第一个成员
不断调用next方法,指针一直往后移动,直到指向最后一个成员
每调用next方法返回一个包含value和done属性的对象
注:需要自定义遍历数据的时候,要想到迭代器
ES异步
Promise
Promise是一个构造函数- 我们可以创建Promise的实例
const p = new Promise() - new出来的Promise实例对象,代表一个异步操作
- 我们可以创建Promise的实例
Promise.prototype上包含一个.then()方法- 每一次
new Promise()构造函数得到的实例对象 - 都可以提供过原型链的方式访问到.then方法, 例如
p.then()
- 每一次
.then()方法用来预先指定成功和失败的回调函数p.then(成功的回调函数,失败的回调函数(可省略))- p.then(result=>{}, error=>{})
.catch(err=>{})方法用来获取链式调用中发生的错误Promise.all(<Promise数组>)发起并行的Promise异步操作,等所有异步操作执行结束后才会执行.then()// 示例代码, thenFs是返回Promise对象的读取文件的第三方库 const promiseList = [ thenFs.readFile("./files/1.txt", 'uft8'), thenFs.readFile("./files/2.txt", 'uft8'), thenFs.readFile("./files/3.txt", 'uft8') ] Promise.all(promiseList) .then( ([r1, r2, r3]) => { // 数组的顺序决定结果的顺序 console.log(r1, r2, r3) }).catch( err => { console.log(err.message) })Promise.race(<Promise数组>)发起并行的Promise一步操作,只要有一个异步完成,立即执行.then()创建具体的异步操作
需要在
new Promise()构造函数期间,传递一个function函数,将具体的异步操作定义到function函数内部function getFile(fpath) { return new Promise(function(resolve, reject){ fs.readFile(fpath, 'utf8', (err, dataStr) => { if(err) return reject(err) resolve(dataStr) }) }) }
async/await
async/await是ES8引入的新语法,用来简化Promise异步操作。以避免链式.then()阅读性差的问题
async function getAllFile(){
const r1 = await thenFs.readFile('path1', 'utf8')
console.log(r1)
const r2 = await thenFs.readFile('path2', 'utf8')
console.log(r2)
}
如果方法内使用了await关键字,方法必须用async修饰
Vue
前言:因为当时学的是黑马Vue2.0, 跟不上时代了, 所以接下来的笔记不是跟着官方课程学的而是自己整理的
本人目前常用Vite+Vue3.0+ts开发, 并且只记录相关笔记
以及会直接使用setup语法糖, 老语法不熟, 真不熟, 记了笔记也只能说是笔记内容没更新
前置知识
必备
- HTML + CSS + JavaScript
- WebAPI(DOM、BOM)
- Ajax
可选
- Node.js
前端四个现代化:
- 模块化(js模块化、css模块化、资源模块化)
- 组件化(复用现有UI结构、样式、行为)
- 规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、Git分支管理)
- 自动化(自动化构建、自动部署、自动化测试)
Vue基础
vue是一套用于构建用户界面的前端框架
vue的主要特性有:数据驱动视图、双向数据绑定
Vite+Vue3.0项目创建: pnpm create vite
Vue中常用指令
指令是vue为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构
内容渲染指令
v-text:""会覆盖元素内部原有内容- {{ }}:插值表达式
v-html:""渲染真正的html内容
属性绑定指令
插值表达式只能用在元素的内容节点中,不能用在元素的属性节点中
v-bind:属性="dataValue" 可以被简写为:属性="dataValue"
<input type="text" v-bind:placeholder="tips">
<input type="text" :placeholder="'awa' + tips">
如果绑定内容需要动态拼接,则字符串的外面应该包裹单引号
事件绑定指令
v-on:[click]="methodsName"可以被简写为"@事件"@:click.prevent="methotsName".prevent是事件修饰符- 事件修饰符
- .prevent阻止默认行为(超链接跳转,表单提交)
- stop阻止事件冒泡
- .capture
- .onde
- .self 等
- $event:原生DOM对象(不常用)
双向绑定指令
v-model最好在表单元素中使用,不然莫得意义,在select中,v-model绑定的是value值v-model修饰符:v-model.number=""自动转成Number类型- .trim过滤首位空格
- .lazy在change而非input时更新
条件渲染指令
v-if条件不满足时直接删除元素v-else-if(必须配合v-if使用)v-else(必须配合v-if使用)v-show条件不满足时添加display:none隐藏元素而不是删除
列表渲染指令
v-for基于一个数组循环渲染一个列表结构- 需要使用item in items形式的特殊语法,其中:
- items 是带循环的数组
- item 是被循环的每一项
<tr v-for="item in list">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
</tr>
- v-for还支持一个可选的第二个参数,即当前项的索引
<tr v-for="(item,index) in list"
- 官方建议:只要用到了 v-for 指令,那么一定要绑定一个 :key 属性,而且尽量把 id 作为 key 的值
- key 的值只能是字符串或数字类型,且不能有重复数据,建议以uid这样的形式绑定key
<tr v-for="(item,index) in list" :key="item.id"></tr>
侦听器
允许开发者监视数据变化,从而针对数据变化做特定的操作
// 侦听一个 getter 函数:
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => { /* ... */ }
)
// 侦听一个 ref:
const count = ref(0)
watch(count, (count, prevCount) => { /* ... */ })
// 侦听多个来源
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { /* ... */ })
监听器本质上是一个函数,需要监视哪个数据的变化,就把数据名作为方法名即可
当使用 getter 函数作为源时,回调只在此函数的返回值变化时才会触发。如果你想让回调在深层级变更时也能触发,你需要使用 { deep: true } 强制侦听器进入深层级模式。在深层级模式时,如果回调函数由于深层级的变更而被触发,那么新值和旧值将是同一个对象。
const state = reactive({ count: 0 })
watch(
() => state,
(newValue, oldValue) => {
// newValue === oldValue
},
{ deep: true }
)
// 直接侦听一个响应式对象时,侦听器会自动启用深层模式
const state = reactive({ count: 0 })
watch(state, () => { /* 深层级变更状态所触发的回调 */ })
停止侦听器:
const stop = watch(source, callback)
// 当已不再需要该侦听器时:
stop()
// 副作用清理
watch(id, async (newId, oldId, onCleanup) => {
const { response, cancel } = doAsyncWork(newId)
// 当 `id` 变化时,`cancel` 将被调用,
// 取消之前的未完成的请求
onCleanup(cancel)
data.value = await response
})
vue项目中src目录的构成:
- assets 文件夹:存放项目中用到的静态资源文件(css样式表、图片)
- components 文件夹:程序员封装的、可复用的组件,都要放到 components 目录下
- main.js 项目入口文件。整个项目的运行,要先执行main.js
- App.vue 项目根组件
组件与生命周期
vue组件就是 .vue 文件啦
注册与使用
每个.vue组件都由3部分构成:
- template 组件的模板结构
- script 组件的JavaScript行为
- style 组件的样式
<script setup lang="ts">
import { ref } from 'vue';
const username = ref("Cloyir");
</script>
<template>
<!-- template中只能有一个根节点, 所以一般会套一个大div -->
<div>
<h1>{{ username }}</h1>
</div>
</template>
<style scoped></style>
使用私有组件的步骤:
使用 import 语法导入需要的组件
import Left from './components/Left.vue'以标签形式使用刚才注册的组件
<div><Left></Left></div>
使用全局组件的步骤
在vue项目的main.js入口文件中,通过Vue.component()方法,可以注册全局组件
// 导入需要全局注册的组件 import Count from '@components/Count.vue' // 参数1: 字符串格式 参数2: 需要被全局注册的组件 Vue.component('MyCount', Count)
props组件属性
props 是组件的自定义属性,在封装通用组件的时候,合理使用 props 可以极大的提高组件的复用性
<template>
<p>{{ foo }}</p>
</template>
<script setup lang="ts">
defineProps<{
foo?: string
}>();
</script>
使用:
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue';
</script>
<template>
<div>
<HelloWorld :foo="'awa'"></HelloWorld>
</div>
</template>
<style scoped></style>
所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。
使用一个对象绑定多个 prop
const post = {
id: 1,
title: 'My Journey with Vue'
}
<Mod v-bind="post" />
<!-- 等价于 -->
<Mod :id="post.id" :title="post.title" />
emits组件事件
事件定义
<!-- MyComponent -->
<button @click="$emit('someEvent')">click me</button>
<!-- 父组件 -->
<MyComponent @some-event="callback" />
<MyComponent @some-event.once="callback" />
事件声明
<script setup>
defineEmits(['inFocus', 'submit'])
// example
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
// 3.3+:另一种更简洁的语法
const emit = defineEmits<{
change: [id: number] // 具名元组语法
update: [value: string]
}>()
</script>
<script setup lang="ts">
const emit = defineEmits({
submit(payload: { email: string, password: string }) {
// 通过返回值为 `true` 还是为 `false` 来判断
// 验证是否通过
}
})
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
</script>
依赖注入
provide 提供
<script setup>
import { provide } from 'vue'
provide(/* 注入名 */ 'message', /* 值 */ 'hello!')
import { ref, provide } from 'vue'
const count = ref(0)
provide('key', count)
</script>
应用层provide
import { createApp } from 'vue'
const app = createApp({});
app.provide('message', 'hello!');
inject 收取
<script setup>
import { inject } from 'vue'
const message = inject('message')
const value = inject('message', '这是默认值') // 防止注入名没有任何组件提供
/* 在一些场景中,默认值可能需要通过调用一个函数或初始化一个类来取得。为了避免在用不到默认值的情况下进行不必要的计算或产生副作用,我们可以使用工厂函数来创建默认值 */
const value = inject('key', () => new ExpensiveClass(), true)
</script>
如果提供的值是一个 ref,注入进来的会是该 ref 对象,而不会自动解包为其内部的值。这使得注入方组件能够通过 ref 对象保持了和供给方的响应性链接。
和响应式数据配合使用
当提供 / 注入响应式的数据时,建议尽可能将任何对响应式状态的变更都保持在供给方组件中。这样可以确保所提供状态的声明和变更操作都内聚在同一个组件内,使其更容易维护。
有的时候,我们可能需要在注入方组件中更改数据。在这种情况下,我们推荐在供给方组件内声明并提供一个更改数据的方法函数
<!-- 在供给方组件内 -->
<script setup>
import { provide, ref } from 'vue'
const location = ref('North Pole')
function updateLocation() { location.value = 'South Pole' }
provide('location', { location, updateLocation })
</script>
<!-- 在注入方组件 -->
<script setup>
import { inject } from 'vue'
const { location, updateLocation } = inject('location')
</script>
<template>
<button @click="updateLocation">{{ location }}</button>
</template>
<!-- 用readonly确保提供的数值不会被修改 -->
<script setup>
import { ref, provide, readonly } from 'vue'
const count = ref(0)
provide('read-only-count', readonly(count))
</script>
组件的生命周期
生命周期指一个组件从创建->运行->销毁的整个阶段,强调的是一个时间段
生命周期函数:是由vue框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行
注意:生命周期强调的是时间段,生命周期函数强调的是时间点
笔记待填充内容:
Vue组件的高级用法
- 动态组件的使用
- 插槽的使用(默认插槽、具名插槽、作用域插槽)
- 自定义指令
- ESLint的使用
路由(Vue-router)
- 路由的基本配置与使用
- 路由重定向
- 嵌套路由、动态路由
编程式导航、路由导航守卫
杂项
axios的基本用法
axios是一个专注于网络请求的库, 但感觉手感不如手码
axios({
method: '请求的类型',
url: '请求的URL地址',
//url中的查询参数,适用于GET请求
params: {},
//请求体参数,适用于POST请求
data: {}
}).then(result => {
//.then用来指定请求成功之后的回调函数
//形参中的 result 是请求成功之后的结果,是Promise对象
//axios在请求到数据之后,在真正的数据之外套了一层壳
//真正的数据保存在result.data中
console.log(result.data)
})