[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TfiG8vPc-1684058312679)(Img/image-20221130130954293.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5g6Yrk7k-1684058312681)(Img/image-20221130131006535.png)]
http请求方法
http1 定义了三种方法 get post head
http2 新增了 options put patch delete trace connect
1get 返回指定的页面信息,并返回
2post 向指定资源提交数据进行处理请求
3options 允许客户端查看服务器的性能
1 获取服务器支持的http请求方法
2 查看服务器性能
4-0 put 使用请求中的负载创建或者替换目标资源。put方法是冥等的,调用一次与连续调用多次是等价的
4-1 patch 可以进行资源的更新,(是对put方法的补充,是用来对已知资源进行局部更新)
put 会有一个 create操作,加入更新的id不存在,会进行创建,
patch 没有这个功能
————
put 如果没有提供完整字段,只提供了其中的一个username字段,则其他字段会被清空
patch 只传想要的username到指定资源,进行局部更新,后端仅更新接收到的字段
5head 请求一个与 GET 请求的响应相同的响应,但没有响应体。只请求资源的头部
该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
6connect 建立一个到由目标资源标识的服务器的隧道。
7trace 沿着到目标资源的路径执行一个消息环回测试。
8delete 删除操作
冥等:不管执行多少次操作,都是实现相同的结果 get put delete 都是冥等操作,而post不是
get | post |
---|---|
倾向于向服务器获取数据 | 倾向于向服务器传递数据 |
get 的请求是可以缓存的 可以从浏览器历史记录中查找到get请求 ,还可以把它收藏到书签中 | post请求不能做缓存 |
明文发送(携带的参数会出现在url 路径中) | 暗文发送 |
url长度是有限制的,又大小限制 2kb左右 | |
浏览器会把http header data一起发送出去,服务器响应200 | 浏览器先发送header ,服务器响应100 continue ,浏览器在发送data,服务器响应200 |
只能请求url编码 | 请求支持多种 |
对数据类型的限制 只允许 ascll 编码 | 都可以 |
跨域问题
跨域产生原因:浏览器的同源策略导致的(域名,协议,端口号,有一个不同就会导致跨域问题)
解决办法
1配置反向代理
config.js
前端设置jsonp
<script>
function json(data){
console.log(data)
}
</script>
<script src="http://localhost:3000/jsonp"></script>
2 服务器端设置请求头
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': '*', // 允许访问的域(协议+域名+端口)
'Access-Control-Allow-Methods': "POST,GET,DELETE,PUT,OPTIONS" // 允许请求方式用着五种
伪类和伪元素
伪类 | 伪元素 |
---|---|
以但冒号开头的关键字,选择器的一种 | 以双冒号开头,向文本中加入全新的html元素 |
对style样式进行操作 | 对dom进行操作 |
:first-child 选中第一个子元素 | ::first-letter 将特殊的样式添加到文本的首字母 |
:hover 鼠标移到元素上 | ::first-line 将特殊的样式添加到文本的首行 |
:foucs 被选中的元素 | ::before 在某元素之前插入内容 |
:active 激活 | ::after后插入内容 |
:link 被访问的链接 | |
:lang 允许传作者定义指定的元素中使用的语言 | |
响应式布局
百分比
rem
媒体查询
@media screen and (max-width: 1000px) {
.box_2 {
display: none;
}
}
// 当 窗口宽度小于 1000px,就使用里面的样式
@media screen and (min-width: 1000px) and (max-width: 1500px) {
.box_2 {
font-weight: 900;
font-size: 40px;
background-color: #fff;
}
}
宽度在1000px 和 1500px 之间 ,就使用里面的样式
后面还可以继续添加 and 来限制视图范围
flex
vw vh
http状态信息
100 | 继续 |
---|---|
101 | 切换协议 |
200 | 一切ok |
201 | 请求成功并创建了新的请求 |
202 | 已接收但尚未处理 |
204 | 无内容,服务器已成功处理,但未返回内容 |
300 | |
301 | 请求的资源永久移动到新的位置 |
302 | 临时移动 |
304 | 请求的资源未修改 |
307 | 临时重定向 |
401 | 要求用户的身份认证 |
404 | 网页错误 找不到页面 |
408 | 请求超时 |
500 | 服务器内部错误 |
501 | 不支持请求的功能 |
canvas 待补充
css2D/3D 动画
2d/3d
css2D transform: | ||
---|---|---|
translate() | 平移 | |
rotate(30deg) | 旋转 | |
scale(num) | 缩放 | num>0 放大 num<0 缩小 |
skew() | 倾斜 | 单位 deg |
matrix() | 组合(把所以2D方式组合到一起) | [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HdcIfuRe-1684058314157)(Img/image-20221125135416742.png)] |
transform-origin | 允许改变元素原点的位置 |
translate3d(x,y,z) | 定义 3D 转化。 |
---|---|
translateX(x) | 定义 3D 转化,仅使用用于 X 轴的值。 |
translateY(y) | 定义 3D 转化,仅使用用于 Y 轴的值。 |
translateZ(z) | 定义 3D 转化,仅使用用于 Z 轴的值。 |
scale3d(x,y,z) | 定义 3D 缩放转换。 |
scaleX(x) | 定义 3D 缩放转换,通过给定一个 X 轴的值。 |
scaleY(y) | 定义 3D 缩放转换,通过给定一个 Y 轴的值。 |
scaleZ(z) | 定义 3D 缩放转换,通过给定一个 Z 轴的值。 |
rotate3d(x,y,z,angle) | 定义 3D 旋转。 |
rotateX(angle) | 定义沿 X 轴的 3D 旋转。 |
rotateY(angle) | 定义沿 Y 轴的 3D 旋转。 |
rotateZ(angle) | 定义沿 Z 轴的 3D 旋转。 |
perspective(n) | 定义 3D 转换元素的透视视图。 单位px 如 n = 600px |
过渡
transition:
-
transition-property:设置元素中参与过渡的属性;
-
transition-duration:设置元素过渡的持续时间;
-
transition-timing-function:设置元素过渡的动画类型;
-
transition-delay:设置过渡效果延迟的时间,默认为 0;
-
transition:简写属性,用于同时设置上面的四个过渡属性。
transition:属性 时间 过渡类型 延迟时间
过渡类型
值 | 描述 |
---|---|
linear | 以始终相同的速度完成整个过渡过程,等同于 cubic-bezier(0,0,1,1) |
ease | 以慢速开始,然后变快,然后慢速结束的顺序来完成过渡过程,等同于 cubic-bezier(0.25,0.1,0.25,1) |
ease-in | 以慢速开始过渡的过程,等同于 cubic-bezier(0.42,0,1,1) |
ease-out | 以慢速结束过渡的过程,等同于 cubic-bezier(0,0,0.58,1) |
ease-in-out | 以慢速开始,并以慢速结束的过渡效果,等同于 cubic-bezier(0.42,0,0.58,1) |
cubic-bezier(n, n, n, n) | 使用 cubic-bezier() 函数来定义自己的值,每个参数的取值范围在 0 到 1 之间 |
动画
animation
@keyframes name{
to:{ 这里填动画执行样式 }
from:{}
}
或者
@keyframes name{
0%:{}
100%:{}
}
animation的属性
-
animation-name:设置需要绑定到元素的动画名称;
-
animation-duration:设置完成动画所需要花费的时间,单位为秒或毫秒,默认为 0;
-
animation-timing-function:设置动画的速度曲线,默认为 ease;
-
animation-fill-mode:设置当动画不播放时(动画播放完或延迟播放时)的状态;
-
animation-delay:设置动画开始之前的延迟时间,默认为 0;
-
animation-iteration-count:设置动画被播放的次数,默认为 1;
-
animation-direction:设置是否在下一周期逆向播放动画,默认为 normal;
-
animation-play-state:设置动画是正在运行还是暂停,默认是 running;
-
animation:所有动画属性的简写属性。
animation: 名称 时间 执行状态 不播放状态 延迟时间 播放次数 播放方式 是否暂停
执行状态
值 | 描述 |
---|---|
linear | 动画从开始到结束的速度是相同的 |
ease | 默认值,动画以低速开始,然后加快,在结束前变慢 |
ease-in | 动画以低速开始 |
ease-out | 动画以低速结束 |
ease-in-out | 动画以低速开始,并以低速结束 |
cubic-bezier(n, n, n, n) | 使用 cubic-bezier() 函数来定义动画的播放速度,参数的取值范围为 0 到 1 之间的数值 |
不播放状态
值 | 描述 |
---|---|
none | 不改变动画的默认行为 |
forwards | 当动画播放完成后,保持动画最后一个关键帧中的样式 |
backwards | 在 animation-delay 所指定的时间段内,应用动画第一个关键帧中的样式 |
both | 同时遵循 forwards 和 backwards 的规则 |
播放次数
值 | 描述 |
---|---|
n | 使用具体数值定义动画播放的次数,默认值为 1 |
infinite | 表示动画无限次播放 |
播放方式
值 | 描述 |
---|---|
normal | 以正常的方式播放动画 |
reverse | 以相反的方向播放动画 |
alternate | 播放动画时,奇数次(1、3、5 等)正常播放,偶数次(2、4、6 等)反向播放 |
alternate-reverse | 播放动画时,奇数次(1、3、5 等)反向播放,偶数次(2、4、6 等)正常播放 |
暂停
值 | 描述 |
---|---|
paused | 暂停动画的播放 |
running | 正常播放动画 |
less基础
1 声明变量
//声明
@width: 10px;
//在属性值中使用变量
#header {
width:@width;
}
2 插值语法
@images: "../img";
body {
background:url("@{images}/white-sand.png");
}
作用域先在自身查找,再从父级向上查找
3.导入外部less
@import "lib.less"
4 &
用 & 可以代替 父级选择器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-68OqDIfw-1684058312683)(Img/image-20221125143732669.png)]
5 支持 + - * / 的运算
属性值的单位将参与换算,如果12px+12px = 24px
当单位无法换算时,取消单位计算,12em+12px = 24
6 转义
转义中的文字将会原样输出,不会进行转化和计算
//less 3.5以下版本
@data: ~"min-width:640px";
//less 3.5+
@min768: (min-width: 768px);
7 混入样式
.borderd {
border-top:2px;
}
#main a {
color:white;
.borderd(); //border-top:2px
}
带参数的混入样式
混入样式就像js中的function 函数封装一样
.border-radius(@radius){
border-radius:@radius;
}
//调用
header {
.border-radius(4px); //border-radius: 4px;
}
8 命名空间
可以将具有具有相同名称的样式区分开
.bundle {
mixin(){
...
}
}
//调用
.bundle>mixin()
Token
cookie essionStorage localStorage
cookie | essionStorage | localStorage | |
---|---|---|---|
存放大小 | 4k | 5k | 5k |
每次都会同步在http请求头中 | stroage只会保存在浏览器中 | ||
cookie 保存在客户的浏览器中
ession 保存在服务器中
essionStorage localStorage 方法
1 存储值 setItem
sessionStorage.setItem("key", "value"); localStorage.setItem("site", "js8.in");
2 获取本地存储的值 getItem
var value = sessionStorage.getItem("key"); var site = localStorage.getItem("site");
3 清除所有本地存储的值 clear
sessionStorage.clear(); localStorage.clear();
还可以用 点 . 操作符 和 [ ] 对数据进行操作
cookie的使用
1 下载插件
npm install --save js-cookie
2.引入
import Cookies from 'js-cookie'
3 使用
添加
// 创建一个名称为name,对应值为value的cookie,由于没有设置失效时间,默认失效时间为该网站关闭时
Cookies.set(name, value)
// 创建一个有效时间为7天的cookie
Cookies.set(name, value, { expires: 7 })
// 创建一个带有路径的cookie
Cookies.set(name, value, { path: '' })
// 创建一个value为对象的cookie
const obj = { name: 'ryan' }
Cookies.set('user', obj)
获取
Cookies.get(name) // 获取指定的cookies
Cookies.get() // 获取所有的cookies
删除
// 删除指定名称的cookie
Cookies.remove(name) // value
// 删除带有路径的cookie
Cookies.set(name, value, { path: '' })
Cookies.remove(name, { path: '' })
数组/字符串/对象/数值/math
数组
concat 和并数组
find es6新增 过滤, //返回数组中第一个满足条件的值 否则返回underfinded
findindex //返回数组中第一个满足条件的下标值(索引) 否则返回-1
indexOf 返回给定元素的第一个索引 否则返回-1
includes 判断数组中是否包含一个指定的值, true 或false //es6新增
pop 可改变原数组
push 可改变原数组
sort 可改变原数组
reserve 可改变原数组
shift 删除第一个 可改变原数组
unshift 向数组开头添加元素 可改变原数组
slice
splice 可改变原数组
join 数组转字符串 可改变原数组
fill 填充数组 //es6新增
// es6新增 一般用于循环遍历(可以用for... of遍历),获取相应的值
entries() 键值对
keys() 键名
values() 键值
// es6新增 拉平
flat
/es6新增
//任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
Array.from() 将类数组和可以遍历的对象转化为真正的数组
Array.of() 将一组值转化为真正的数组
fill
fill 可以接收三个参数
1.填充内容
2.开始填充的位置
3.结束位置(不包含改位置,左闭右开区间)
findIndx/find
可以接收三个参数,value index array (当前值,下标,原数组)
在这里插入图片描述
findof/includes
两个参数
1.要检索的值
2.开始检索的位置
indexof 无法识别NaN
includes 可以识别NaN
flat
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1soNwfQO-1684058312685)(…/…/六星教育/物语的超级笔记家/所有笔记/img/image-20221221102325157.png)]
数组转字符串
let arr = [1,2,,4]
console.log(arr.join('$')); //1$2$$4
console.log(arr.toString('$')); //1,2,,4
复制数组的方法
let a1 = [1,3]
let a2 = a1.concat()
a2[0] = 9
console.log(a1); // [1, 3]
es6新增
// 结构赋值
const a2 = [...a1]; / 第一种
const a2 = [...a1]; / 第二种
合并数组
arr1.concat(arr2, arr3);
/es6新增方法 解构赋值
[...arr1, ...arr2, ...arr3]
reduce
let arr = [1,2,3,4]
let newArr = arr.reduce((pre,cur,index,arr) => {
return pre + cur
})
console.log(newArr); // 10
便利数组 map
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
便利数组 fliter
filter() 循环返回一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
数组去重
set
var arr = [1,1,8,8,12,12,15,15,16,16];
function unique (arr) {
return Array.from(new Set(arr))
}
console.log(unique(arr))
//[1,8,12,15,16]
filter
var arr = [1, 1, 8, 8, 12, 12, 15, 15, 16, 16];
function unlink(arr) {
return arr.filter(function (item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
});
}
console.log(unlink(arr));
字符串
charAt()和charCodeAt()方法都可以通过索引来获取指定位置的值:
toLowerCase() 和 toUpperCase()方法可以用于字符串的大小写转换
split() 字符串变数组
indexOf(a,b)通过字符查找下标,a:要查找的字符,b:开始查找的位置
lastIndexOf() 返回最后一次查找到的位置
// 检测字符串中是否含有某个元素 es6 新增 都支持第二个参数n,表示开始搜索的位置
includes() 判断是否包含子元素 // 从n 开始到结束
startsWith() 该方法用于检测字符串是否以指定的子字符串开始 // 从n 开始到结束
endsWith() 该方法用来判断当前字符串是否是以指定的子字符串结尾。// 针对前 n 个字符
substr()、substring()和 slice() 方法都可以用来截取字符串。
substring(start,end) 左闭右开
slice(0,-1) // 从 0开始截取到最后一个,但不包括 最后一个 负数代表从后面开始数
//消除空白符
trim()
trimStart()和trimEnd() // 消除收尾空白符 es6新增
repeat() 方法返回一个新字符串,表示将原字符串重复n次: // es6新增
parseInt()和parseFloat()方法都用于将字符串转为数字。
如果参数字符串的第一个字符不能被解析成为数字,则 parseFloat 返回 NaN。
//es6新增
String.fromCodePoint() 可以识别大于 oxFFFF的字符
String.raw() 返回一个 斜杠会被转义 的字符串
// 补全字符串 第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。
padStart()
padEnd()
matchAll() 返回一个正则表达式在当前字符串的所有匹配
String.raw()
专注于模板字符串的标签函数
console.log(`Hi\n${2+3}`);
console.log(String.raw`Hi\n${2+3}`);
padEnd()
let str = '卡卡西'
console.log(str.padEnd(5,'!!!!'));
对象
Object.keys() 用来遍历对象的属性(以数组的形式返回对象的属性名)
Object.create() 方法创建一个新对象
Object.freeze() 冻结对象,被冻结的对象只能读取,不可修改
Object.isFrozen() 判断对象是否被冻结
Object.getOwnPropertyNames() 也可以便利对象的属性
Object.assign()方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象。 Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。
Object.hasOwnProperty() 返回一个布尔值
用来检测对象自身属性中是否具有指定的属性。和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。
返回一个布尔值
Object.isPrototypeOf() 用于测试一个对象是否存在于另一个对象的原型链上。
Object.defineProperty()劫持变量的set和get方法,将属性添加到对象,或修改现有属性的特性
Object.seal() 密封一个对象 可以修改这个对象的属性值,但不能修改属性名,不能太添加,删除该对象的属性
Object.isSealed() 判断对象是否被清空
删除对象的属性 delete
let mm = {
name: "卡卡",
love: "卡卡西",
};
delete mm.name;
获取属性的个数的方法:
Object.keys().length
或者
Object.getOwnPropertyNames().length
获取属性的方法 / 遍历对象
1 Object.keys() 只能遍历自己的对象上的可枚举的属性,不能遍历自己原型上可枚举的属性。
2 Object.getOwnPropertyNames() 它遍历自身对象的所有属性,包括可枚举不可枚举,但是原型上的属性是无法遍历的。
3 for(var p in data) 遍历对象的每一个可枚举属性,包括原型链上面的可枚举属性
解冻被 freeze冻结的对象
Object.freeze( let tableData = { ... } ) 冻结对象
JSON.parse(JSON.stringify(tableData)) 解冻对象
获取对象
let data = {
id:1,
}
向对象中添加数据
this.obj['set'] = '开车来接我'
console.log('add',this.obj);
obj[i] i 为obj 对象前 的 索引
这个num 与需要插叙的字段保持一致 如 id
header: '大脑',
obj: {
1: {
id: 1,
content: '天气阴'
},
2:{
id:2,
content:'去加餐'
},
3:{
id:4,
content:'坐地铁'
},
},
ID:[1,2,4,5]
}
},
mounted() {
// this.actionDev()
this.objDev()
},
methods: {
actionDev() {
this.$store.dispatch('actionsTest')
},
objDev(){
let newData = this.ID.map(el => {
return this.obj[el]
}).filter(el => el)
console.log('getObj',newData);
}
JSON
JSON.stringify() 将 JavaScript对象转化为字符串
在向服务器发送数据的时候一般是字符串
JSON.parse() 将 json字符串转对象
JSON.parse(JSON.stringify(tableData)) 深拷贝
数值
// es6 新增
Number.isFinite() 检测数值是否是有限的 只有有限的number 才为true
Number.isNaN() 检测一个值是否为NaN
//es6将全局方法的parseInt()parseFloat()转到Number上
Number.parseInt() 整数
Number.parseFloat() 小数/浮点数
Number.isInteger() 判断一个数值是否要为整数
Math
// es6 新增
Math.trunc(4.9) // 4 去除小数
Math.sign() 判断正数负数还是 0
es6新增指数运算符
2 ** 3 // 8
2 ** 3 ** 2 // 相当于 2 ** (3 ** 2) !!这是右结合!! 从右边开始运算的
可以与等号结合使用
let b = 4;
b **= 3; // 等同于 b = b * b * b;
BigInt
BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
/* 原本 js 只能表示小于 2 的 2014次方的值 */
为了与 Number 类型区别,BigInt 类型的数据必须添加后缀n
类型判断
typeof 只能判断基本类型
数组
Array.prototype.isPrototypeOf(obj)
es6新增
为什么单独拿出来:因为 es6修改的内容最多(很多很多)
es6 新增
- let const
- 解构赋值
- 箭头函数
- set map
- Symbol
- Proxy 代理
- Reflect
- Iterator 遍历器
- Generator 函数
- async
函数
默认值
/允许为函数的参数设置默认值
function log(x, y = 'World') {
console.log(x, y);
}
/设有默认值的函数 是 惰性传值 每次都重新计算默认值表达式的值
let x = 99;
function foo(p = x + 1) {
console.log(p);
}
foo() // 100
x = 100;
foo() // 101
获取函数名称 name
name 属性 返回 函数名称
const fnData = () => {
}
console.log(fnData.name); //fnData
对象
对象可以简写了
Object.is
用法和 === 严格等于一样,只有一点点差别
Object.assign
合并对象
参数
- 目标对象
- 后面的参数都是需要合并进来的对象 ,有属性相同时,后面的会覆盖前面的值
Object.keys(),Object.values(),Object.entries()
/ 返回一个数组
Object.keys() 获取对象的键名
Object.values() 键值
Object.entries() 键值对
Object.fromEntries() 是 entries的逆操作 键值对转对象
null判断 ?? 默认值
map 和set 都是新增的表示集合的数据结构
set
返回一个类似于数组的方法,可以用Array.form(arr) 来转化为真正的数组
let arr = [1,2,3,4,5,5,10]
let news = new Set(arr)
console.log(news);
添加
news.add(‘哎呦喂’)
删除
news.delete(‘哎呦喂’)
判断
news.has(‘哎呦喂’)
清空
news.clear()
WeakSet
与set 用法类似,但只能存放对象
Map
因为 对象只接受字符串作为键名 (如使用 dom 节点,用作键 [dom] 时,会被自动转义为 [object HTMLDivElement] )
now map 很好的解决了这个问题啦
map 键的范围不在局限与字符串了 啥啥都可以当作它的 键了
如
map 也没有取到????
脸有点痛!!!
Object.create()
const map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
const map = new Map();
const k1 = ['a'];
const k2 = ['a'];
map
.set(k1, 111)
.set(k2, 222);
map.get(k1) // 111
map.get(k2) // 222
Map 的键实际上是和内存地址绑定的,只要内存地址不一样,就视为两个键
const mm = new Map()
mm.set(p,'卡卡西') // 设置
mm.get(p) // 获取
mm.size // 1
mm.delete(p) // 删除
mm.clear()清除所有成员 // 无返回值
如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0
和-0
就是一个键
symbol
1 新增 description
属性 读取 symbol 转为字符串
let str = Symbol('卡卡西')
console.log(str);
console.log(str.description);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7cFpVaBO-1684058312691)(./Img/image-20230110162427428.png)]
2 作为属性名的 symbol
由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名
注意,Symbol 值作为对象属性名时,不能用点运算符 ! ! !
上面代码中,因为点运算符后面总是字符串,所以不会读取
mySymbol
作为标识名所指代的那个值,导致a
的属性名实际上是一个字符串,而不是一个 Symbol 值。同理,在
对象的内部
,使用 Symbol 值定义属性时,Symbol 值必须放在方括号
之中。 let obj ={ name:‘卡开心’ }
let attr = Symbol()
obj[attr] = ‘来吧’
console.log(obj);
3 Object.getOwnPropertySymbols()
Symbol 作为属性名,遍历对象的时候,该属性不会出现在for...in
、for...of
循环中,也不会被Object.keys()
、Object.getOwnPropertyNames()
、JSON.stringify()
返回。
let obj ={
name:'卡开心'
}
let attr = Symbol()
obj[attr] = '来吧'
console.log(Object.keys(obj)); 这里 attr 没有被遍历到
使用 Object.getOwnPropertySymbols() 遍历到了,但也只能遍历到 symbol 属性名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dnLcOmtZ-1684058312693)(./Img/image-20230110165950757.png)]
-
Symbol.for
为 Symbol 类型的值,进行登记处理 并且登记的值时全局环境的(不论你是不是在全局中定义的)/ 未登记的 symbol 类型的值 let s1 = Symbol('扣扣') let s2 = Symbol('扣扣') console.log(s1 === s2); // 返回false
如果我们想要使用同一个symbol 值,可以使用 for 属性
它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建一个以该字符串为名称的 Symbol 值,并将其注册到全局。
/ 以登记的Symbol 类型的值 let s1 = Symbol.for('扣扣') let s2 = Symbol.for('扣扣') console.log(s1 === s2); // 返回 true
-
Symbol.keyFor
返回一个已经登记的symbol 值 的 key
let s = Symbol('qq') let s1 = Symbol.for('扣扣') console.log(Symbol.keyFor(s)); console.log(Symbol.keyFor(s1));
6 es6新增11 个内置的 Symbol 值 ?? 回头补充
Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义
new Proxy(target, handler)
target:拦截的目标对象
handler:拦截行为
方法 一共 13中,其他的待补充
- set
- get
- apply
- has
- deleteProperty
最基本使用示例
const handler = {
get(obj, prop) {
console.log('获取了');
return obj[prop]
},
set() {
console.log('修改了');
}
}
let proxy = new Proxy({}, handler)
proxy.name = '卡卡西'
参数设置:
set
set(target, property, value, receiver){}
- target 目标对象
- property 被设置的属性名
- value 新的属性值
- receiver 最初被调用的对象
get
get(target, property, receiver){}
apply
apply方法拦截函数的调用、call和apply操作
。
apply方法可以接受三个参数,分别是目标对象、目标对象的上下文对象(this)和目标对象的参数数组
。
has
has方法用来拦截HasProperty操作
,即判断对象是否具有某个属性时,这个方法会生效。典型的操作就是in运算符。
has方法可以接受两个参数,分别是目标对象、需查询的属性名
。
deleteProperty
deleteProperty方法用于拦截delete操作
,如果这个方法抛出错误或者返回false,当前属性就无法被delete命令删除。
取消操作 revocable
const handler = {
get(target, property, receiver) {
},
set(target, property, value, receiver) {
console.log('修改了');
}
}
let obj = {
name:'卡卡西ya'
}
let {proxy, revoke} = Proxy.revocable(obj, handler);
proxy.name = '修改name'
revoke()
proxy.name = '还可以修改吗'
this指向问题
let obj = {
name: '卡卡西ya',
m() {
console.log(this === proxy);
}
}
const proxy = new Proxy(obj, {});
obj.m() // false
proxy.m() // true
用 proxy 代理后,obj 中的this 不在指向 obj 而是指向 proxy了
Reflect
为了操控对象而诞生的新的API
用途:
1 - 错误捕获
使用 try catch
try {
Object.defineProperty(target, property, attributes);
// success
} catch (e) {
// failure
}
reflect
让它看起来更加合理了
if (Reflect.defineProperty(target, property, attributes)) {
// success
} else {
// failure
}
2 - 函数式操作
让 object 的行为 都变为了 函数式的操作
一共 13
个静态 方法
Reflect.get(target, name, receiver)
参数
- target : 对象(obj)
- name: 操作的属性
- receiver:
修改 this 指向
,将this 指向其他作用域
Reflect.set(target, name, value,receiver)
参数:其他的参数与 get 相同
value:设置的值
Reflect.has(target,name)
判断 对象 target 中 是否存在 name 属性 , 返回 true 或者 false
Iterator
interator 为什么出生:为所有数据结构,提供了一种统一的访问机制
Generator
什么是异步
当一个任务是不是连续完成的,就可以理解为该任务被分成了多个阶段,先执行第一段,然在第一段准备过程中,去执行其他任务,等第一段ok了,再去执行第二段任务
如:在 执行js 时,遇到了 setTimeout(延迟 1s) 时,发现它是异步的,就会把它放到令一个任务队列中,去执行其他的主线任务,在1s后,在去执行这个 setTimeout 函数的内容
什么是同步
一步一步的执行代码,只有上一步任务执行完毕,才可以去执行下一步任务
目的:解决异步编程
1 在 function 后面 添加个 星号 *
2 关键字: yield 表达式
3 关键方法 : next()
使用:每次 使用 next() 都
function* he(){
yield '卡卡西'
yield '佐助'
return 'over'
}
var ant = he()
console.log(ant.next());
console.log(ant.next());
console.log(ant.next());
async
async 是 Generator 的语法糖
async 将 function 后面的 * 替换成了 async , 将 yield 替换成了 await
async:表明函数是异步的
await:等待后面的表达式结果
async 有个内置执行器,不用像 Generator 一样,需要手动next 才可以执行,它可以自动执行,然后输出结果
返回值为 promise 对象
const file = async function() {
return await ...
}
file.then()
file.catch()
返回的是promise对象,所以可以用 .then 和 .catch 来捕获成功或失败
可以用 try … catch 来捕获错误
const file = async function() {
try{
await ...
}catch(){}
}
各种居中对齐的方法
1 flex
2 absolate
3 margin 和 transform 配合使用
4 absolate 和 margin
5 网格布局 grid
闭包
可以使用其他函数作用域中的变量的函数称之为闭包
案例一 获取区间
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kgve0Txf-1684058312697)(Img/image-20221129141825856.png)]
案例二 移动动画
let boxS = document.getElementsByClassName("boxBorder");
tabList = Array.from(boxS);
tabList.forEach(function (item) {
item.addEventListener("click", function () {
let left = 1;
setInterval(function () {
item.style.left = left++ + "px";
}, 10);
});
});
这样写:再次点boxS小球是,会发送混乱抖动现象
可以给动画加个开关 (防抖)
定义个变量 bind来判断动画是否已经执行 使用if来判断,若以执行,则不再执行if里面的代码了
内存泄漏的解决方法
- 解除循环引用 (重新给你需要的东东赋值)
- 将闭包引用的外部函数中活动的对象清除 (将外部的 item 对象 赋值为 null 即清除)
问题??
闭包里的数据是一直保存在内存中,还是在闭包函数执行完毕后直接销毁
变量会一直保存在内存中,下一次调用时,使用的是保存在内存中的值
promse
js异步编程的解决方案
异步编程
1fs 文件操作
2数据库操作
3ajax
4定时器
在promse之前,是使用回调函数来进行异步操作
为什么使用promse
1支持链式调用,解决回调地狱问题
2指定回调函数的方式更加灵活
promse是一个构造函数
promse的状态变化
- pedding 变为 resloved 成功
- pedding 变为 rejectd 失败
一个promse对象只能改变一次
promse方法
.then
指定成功和失败的回调
.catch
只指定失败的回调
promise.resolve()
resolve是promse本身的方法 不能在promise的实例化对象中使用
如果promise.resolve() 参数传递的是非promise对象,则直接返回成功的promise对象
如果promise.resolve() 参数传递的是promise对象,则根据返回的结果决定reslove的结果
上面报红的原因是因为失败没有捕获,用catch捕获错误就好了
p3.catch(err => {
sonsloe.log(err)
})
promise.reject()
promse本身的方法 不能在promise的实例化对象中使用
会返回失败的promise对象
promise.all
promse本身的方法 不能在promise的实例化对象中使用
传入的参数是一个数组
只有数组中的所有都成功,才能返回失败的回调,只要有一个失败了,就是失败
成功返回的结果会以数组的形式返回
有一个失败了
promise.race
会将第一个完成promise的结果状态作为最终的返回值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yUVU5td7-1684059869616)(Img/image-20221129175904166.png)]
改变状态的三种方式
1.resolve
2.reject
3.throw
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hhXX3Ykf-1684059869616)(Img/image-20221129180547293.png)]
问题一:能否执行多个回调
答案是肯定的呀
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LW5G0qaG-1684059869617)(Img/image-20221130092327422.png)]
问题二: 改变回调函数状态和回调函数谁先执行
啊啊啊!!! 这样说好像也有点问题 总之,reslove() 先执行, 再 去执行 .then中的回调函数
只有先执行reslove() .then中的成功或失败的回调调用
在 new Promise() 中reslove 中为微任务时(如延迟器)异步任务队列 会执行 .then (但无法执行 .then 成功或失败的回调) 等 setTiemout中的 reslove() 执行后,才回去调用 .then中 成功的回调函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xoFnsr2e-1684059869617)(Img/image-20221130094204551.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcmACWm3-1684059869618)(Img/image-20221130100259362.png)]
问题三 串联多个任务
可以串联多个任务,进行链式调用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFrVSpt4-1684059869618)(Img/image-20221130103333747.png)]
第二个有返回值的情况
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Twdef9U4-1684059869619)(Img/image-20221130103515112.png)]
问题四 异常穿透
在链式调用后面添加个 .catch函数去捕获异常
最后一个 catch 会捕获上面所有步骤中的错误,在p.then 中出现的错误也捕获到
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UFPkzabI-1684059869620)(Img/image-20221130104130107.png)]
问题五 中断promsie 链
只有返回一个 pedding状态的函数才可以中断
因为then 只有状态改变时才可以执行,让前面的状态一直为pedding ,则后面的then方法就无法调用了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B1zBDTac-1684059869620)(Img/image-20221130104916350.png)]
async/await
ansyc 声明函数的返回值为promsie对象
promsie的结果由promise的返回值来确定的
async function main(){
// 返回值为 非 promise 类型
return '卡卡西'
}
let result = main()
console.log("one",result);
async function mainTwo(){
// 返回值为 非 promise 类型
return new Promise((resolve,reject) => {
resolve("成功了")
})
}
let resultTwo = mainTwo()
console.log("two",resultTwo);
async function mainThere(){
return new Promise((resolve,reject) => {
reject("失败了")
})
}
let resultThere = mainThere()
console.log("there",resultThere);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8LEvGsOc-1684059869621)(Img/image-20221130110202284.png)]
await 和失败捕获
用 try catch 来捕获失败
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPdC8N6O-1684059869621)(Img/image-20221130111131463.png)]
案例一 抽奖
const btn = document.getElementsByTagName('button')[0]
let showPrize = document.getElementsByTagName('span')[0]
btn.addEventListener('click',function(){
const p = new Promise((resolve,reject) => {
setTimeout(() => {
let n = rand(1,100);
if(n<=30){
resolve() // 将promse 的状态设置为成功
}else{
reject() // 将promse 的状体设置为失败
}
},1)
})
p.then(()=>{
//这里是then的第一个参数,是成功的回调
showPrize.innerHTML = '中将啦'
},()=>{
//这里是then的第二个参数,是失败的回调
showPrize.innerHTML = '又没中奖'
})
})
function rand(a,b){
return Math.ceil(Math.random()*(b-a+1) + a-1)
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qm6pDa39-1684059869621)(Img/image-20221129155134233.png)]
关键词
resolve() // 将promse 的状态设置为成功
reject() // 将promse 的状体设置为失败
p.then(()=>{
//这里是then的第一个参数,是成功的回调
showPrize.innerHTML = ‘中将啦’
},()=>{
//这里是then的第二个参数,是失败的回调
showPrize.innerHTML = ‘又没中奖’
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u4J5t1dX-1684059869622)(Img/image-20221129155706418.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d3iSGcPO-1684059869622)(Img/image-20221129155720193.png)]
案例二 fs读取文件
fs模块可以读取文件 这是node的内置模块
function mineReadFile(path){
return new Promise((resolve,reject) => {
require('fs').readFile(path,(err,data) => {
if(err) reject(err)
resolve(data)
})
})
}
mineReadFile('./fs.txt').then(value => {
console.log("value",value.toString());
},err=>{
console.log(err);
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-euSPxExo-1684059869623)(Img/image-20221129162742359.png)]
这里将promse作为返回值
案例三 封装ajax 失败了,回头补充
js 事件委托
例子
<div>
<ul class="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
$('.box')[0].addEventListener('click',function(e){
const t = e.target
// 判断是否匹配目标元素
if (t.nodeName.toLocaleLowerCase() === 'li') {
console.log(t)
console.log(t.innerHTML);
}else{
console.log("no");
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnBpGmYn-1684059869623)(Img/image-20221206162745243.png)]
e.target 获取每次点击的实例
事件委托的优点
可以动态的绑定事件
spa框架
单页面框架
将所有活动都限制在一个web 页面中,整个项目只有一个html文件
在页面初始化时,就加载相应的html js css 页面加载完成后,spa 不会因为用户的操作而进行页面的重新加载或者跳转,利用 js 动态的切换 html,从而实现ui 与用户的交互
优点:
- 提升页面切换体验
- 前后端分离开发
- 减轻服务器压力(服务器只管给数据就好了,不用管逻辑和页面)
缺点:
- seo 难度高(因为所有的内容都在一个页面中动态替换显示)
- 前进后退管理
- 初次加载耗时多(解决方法:路由按需加载)
window事件
页面跳转
windows.location.href="/url"
events 事件
clientX/Y | 鼠标距离窗口的位置 |
---|---|
pageX/Y | 鼠标距离窗口加滚动条的距离 |
offsetX/Y | 鼠标距离dom盒子的距离 如果在canvas中滑动鼠标,判断光标是否在某个闭合路径内,光标位置需用offsetX、offsetY表示,而不是clientX、clientY,因为在绘制路径时的坐标是相对于canvas的。 |
layerX/Y | 相对当前坐标系,没有设置绝对定位或相对定位,以页面为参考点,如果设置了,触发事件元素盒子模型的border区域的左上角为参考点。 |
screenX/Y | 相对显示器屏幕左上角的距离 |
vue2
vue键盘事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XCwQ52ys-1684059869623)(Img/image-20221205170325334.png)]
一 传值
1.父组件向子组件传值
//子组件:用props接受
//父组件:用v-bind: 传值
2.子组件向父组件传值: emit
子组件: this.$emit("toVal",data) //接受
父组件: @toVal = "getData" getData(newVal){conslog.log(newVal)} //参数newVal就是传过来的值
3.中央事件车.js
3.1 EventBus.js 文件
import Vue from 'vue'
export default new Vue()
3,2 要传值的文件1
import eventBus from './EventBus'
eventBus.$emit('pushMsg',this.childNum++) // 通过事件总线发送消息
3.3要接收值的文件2
eventBus.$on('pushMsg', (children1Msg) => { // 通过事件车接收消息
this.msg = children1Msg
})
4.通过 $parent / $children 或 $refs 访问组件实例
<hello-world ref="getSon"></hello-world>
4-1 $refs
methods:{
getSonFn(){
console.log(this.$refs.getSon);
console.log(this.$refs.getSon.title); // 卡卡西 在子组件里定义了tilte = "卡卡西"
this.$refs.getSon.active() // 也可以调用子组件中的方法
}
}
4-2 $children
console.log(this.$children[0].title); // this.$children 以数组的形式,获取到了所有的组件实例 ,因为一个父组件可以有多个子组件
4-3 $parent
console.log(this.$parent.parentData); // 打印:我是父组件数据 this.$parent 获取父组件实例
5.provide/inject。 多层父子通信,
父组件下的所有子组件 都可以获取到父组件中provide 中的值
// 父组件
provide:{
name:'i am your 爸爸'
}
// 子组件的子组件
inject:['name'],
methods:{
getPP(){
console.log('inject',this.name); // i am your 爸爸
}
}
二 组件编写
//组件
<template>
<div>
<p>光遇-活动日</p>
<slot name="act"></slot>
</div>
</template>
//使用
<hello-son>
<p slot="act">1.1-1.12 冬日活动</p>
</hello-son>
vue 动态组件 用于实现在指定位置上,动态加载不同的组件
<component :is="componentTag"></component>
三 导航元信息
在路由列表中(router index.js 文件里)每个路由都有一个meta 元数据字段,这里我们可以设置自定义信息,可供页面或者路由钩子函数中使用
{
path: '/',
name: 'home',
component: HomeView,
mate:{
isShow:false
}
},
通过 {{ $router.meta.isShow }} $router.meta 来获取 mate 里面的信息, 也可以这样子对meta 里面的信息进行修改
四 hash路由和history 路由
[]: https://juejin.cn/post/7037282729485959204
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fb6AetqD-1684059869624)(Img/image-20221206145247559.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-keRZ5J9d-1684059869624)(Img/image-20221206151726475.png)]
hash路由 | history路由 |
---|---|
路由后面会添加 # 号 | 无 # |
监听hash值的变化 | 监听url 路径的变化,需要客户端和服务器端的支持 |
hash值的变化不会导致浏览器向服务器发送请求,刷新不会存在404问题 | 访问每一个页面,浏览器会重新发起请求(会刷新浏览器),如果没有匹配当前的url,就会出现404错误?? |
hash值的变化会触发hashchagne事件 | 前进后退会触发 popstate事件 |
history.pushState(obj,title,url) 在历史中添加一条记录,但不会触发页面刷新 | |
history.replaceState(obj,title,url) 修改记录 | |
ie兼容到了 ie8 | ie 兼容 ie10 |
锚点问题
<div>
<a name="mao">顶部</a>
<div class="mao"></div>
<a href="#mao">跳转顶部</a>
</div>
hash模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tPhuPEx2-1684059869625)(Img/image-20221207133332543.png)]
history 模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kuHIZvOI-1684059869625)(Img/image-20221207133430052.png)]
hash 和 history 共有的方法
history.back()
history.forward()
history.go(number)
history.state:History 堆栈最上层的状态值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ggpis21B-1684059869625)(Img/image-20221207110346608.png)]
widow.history 执向History 对象[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4QCOJZ22-1684059869626)(Img/image-20221207110639062.png)]
hashchange事件
// window.onhashchange 写在 router index.js 文件中生效 可以监听到每次hash值的变化
window.addEventListener('hashchange',()=>{ //监听到的是浏览器的前进后退事件,自己写的按钮跳转时监听不到
console.log('hash值',window.location.hash);
})
// 监听到hash值的变化
// event.oldURL event.newURL 监听到的是整个url
window.addEventListener('hashchange',(event) => {
console.log('old',event.oldURL);
console.log('new',event.newURL);
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XnvlTwPW-1684059869626)(Img/image-20221207093935174.png)]
hash 模式 不会将hash 值发送给 服务器 ,自己可以配置路由信息
history 模式 会将 路由信息发送给 服务器
history.pushState(obj,title,url)
object:是一个对象,通过 pushState 方法可以将该对象内容传递到新页面中。如果不需要这个对象,此处可以填 null。
title:指标题,几乎没有浏览器支持该参数,传一个空字符串比较安全。
url:新的网址,必须与当前页面处在同一个域。不指定的话则为当前的路径,如果设置了一个跨域网址,则会报错
add(){
history.pushState(null,null,'http://localhost:8081/history')
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NYeuYyTA-1684059869626)(Img/image-20221207111915381.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-68CKmY58-1684059869627)(Img/image-20221206153649393.png)]
五 路由懒加载
当加载路由文件时,首先要加载所有引入 的路由组件,这样会影响页面的加载速度,会延长首页的白屏时间
解决方法:路由懒加载,只有在需要这个路由时,才会加载这一部分的js 代码 就是 按需加载
写法1:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
写法2:
component:resolve => require(['@/pages/task'],resolve)
六input 输入框
获取 input 的节点后,用
this.$ref
七vuex
State 存放数据
Getter 相当于state的计算属性
Mutation 同步方法
调用 mutation 方法
this.$store.commit('increment')
Action 异步方法
异步
的mutation操作,不过提交的是mutation
。
actions: {
increment ({ commit,state,getters }) {
commit('increment')
}
在action commit(同步方法名称)
就可以调用同步方法
script 中触发
this.$store.dispatch
参数commit
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
date:'2023-02-03'
},
getters: {
},
mutations: {
LogDat(state){
console.log(state.date);
}
},
actions: {
actionsTest({commit}){
commit('LogDat') // 直接调用mutations中的方法
console.log(commit);
}
},
modules: {
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3X6evXx9-1684059869627)(./Img/image-20230203101523921.png)]
例子
<div>
<ul class="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
$('.box')[0].addEventListener('click',function(e){
const t = e.target
// 判断是否匹配目标元素
if (t.nodeName.toLocaleLowerCase() === 'li') {
console.log(t)
console.log(t.innerHTML);
}else{
console.log("no");
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7wtKVL8N-1684058312706)(Img/image-20221206162745243.png)]
e.target 获取每次点击的实例
事件委托的优点
可以动态的绑定事件
spa框架
单页面框架
将所有活动都限制在一个web 页面中,整个项目只有一个html文件
在页面初始化时,就加载相应的html js css 页面加载完成后,spa 不会因为用户的操作而进行页面的重新加载或者跳转,利用 js 动态的切换 html,从而实现ui 与用户的交互
优点:
- 提升页面切换体验
- 前后端分离开发
- 减轻服务器压力(服务器只管给数据就好了,不用管逻辑和页面)
缺点:
- seo 难度高(因为所有的内容都在一个页面中动态替换显示)
- 前进后退管理
- 初次加载耗时多(解决方法:路由按需加载)
window事件
页面跳转
windows.location.href="/url"
events 事件
clientX/Y | 鼠标距离窗口的位置 |
---|---|
pageX/Y | 鼠标距离窗口加滚动条的距离 |
offsetX/Y | 鼠标距离dom盒子的距离 如果在canvas中滑动鼠标,判断光标是否在某个闭合路径内,光标位置需用offsetX、offsetY表示,而不是clientX、clientY,因为在绘制路径时的坐标是相对于canvas的。 |
layerX/Y | 相对当前坐标系,没有设置绝对定位或相对定位,以页面为参考点,如果设置了,触发事件元素盒子模型的border区域的左上角为参考点。 |
screenX/Y | 相对显示器屏幕左上角的距离 |
vue2
vue键盘事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H26pd9F0-1684058312706)(Img/image-20221205170325334.png)]
一 传值
1.父组件向子组件传值
//子组件:用props接受
//父组件:用v-bind: 传值
2.子组件向父组件传值: emit
子组件: this.$emit("toVal",data) //接受
父组件: @toVal = "getData" getData(newVal){conslog.log(newVal)} //参数newVal就是传过来的值
3.中央事件车.js
3.1 EventBus.js 文件
import Vue from 'vue'
export default new Vue()
3,2 要传值的文件1
import eventBus from './EventBus'
eventBus.$emit('pushMsg',this.childNum++) // 通过事件总线发送消息
3.3要接收值的文件2
eventBus.$on('pushMsg', (children1Msg) => { // 通过事件车接收消息
this.msg = children1Msg
})
4.通过 $parent / $children 或 $refs 访问组件实例
<hello-world ref="getSon"></hello-world>
4-1 $refs
methods:{
getSonFn(){
console.log(this.$refs.getSon);
console.log(this.$refs.getSon.title); // 卡卡西 在子组件里定义了tilte = "卡卡西"
this.$refs.getSon.active() // 也可以调用子组件中的方法
}
}
4-2 $children
console.log(this.$children[0].title); // this.$children 以数组的形式,获取到了所有的组件实例 ,因为一个父组件可以有多个子组件
4-3 $parent
console.log(this.$parent.parentData); // 打印:我是父组件数据 this.$parent 获取父组件实例
5.provide/inject。 多层父子通信,
父组件下的所有子组件 都可以获取到父组件中provide 中的值
// 父组件
provide:{
name:'i am your 爸爸'
}
// 子组件的子组件
inject:['name'],
methods:{
getPP(){
console.log('inject',this.name); // i am your 爸爸
}
}
二 组件编写
//组件
<template>
<div>
<p>光遇-活动日</p>
<slot name="act"></slot>
</div>
</template>
//使用
<hello-son>
<p slot="act">1.1-1.12 冬日活动</p>
</hello-son>
vue 动态组件 用于实现在指定位置上,动态加载不同的组件
<component :is="componentTag"></component>
三 导航元信息
在路由列表中(router index.js 文件里)每个路由都有一个meta 元数据字段,这里我们可以设置自定义信息,可供页面或者路由钩子函数中使用
{
path: '/',
name: 'home',
component: HomeView,
mate:{
isShow:false
}
},
通过 {{ $router.meta.isShow }} $router.meta 来获取 mate 里面的信息, 也可以这样子对meta 里面的信息进行修改
四 hash路由和history 路由
[]: https://juejin.cn/post/7037282729485959204
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-StqvRXRx-1684058312707)(Img/image-20221206145247559.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jRVyhevT-1684058312707)(Img/image-20221206151726475.png)]
hash路由 | history路由 |
---|---|
路由后面会添加 # 号 | 无 # |
监听hash值的变化 | 监听url 路径的变化,需要客户端和服务器端的支持 |
hash值的变化不会导致浏览器向服务器发送请求,刷新不会存在404问题 | 访问每一个页面,浏览器会重新发起请求(会刷新浏览器),如果没有匹配当前的url,就会出现404错误?? |
hash值的变化会触发hashchagne事件 | 前进后退会触发 popstate事件 |
history.pushState(obj,title,url) 在历史中添加一条记录,但不会触发页面刷新 | |
history.replaceState(obj,title,url) 修改记录 | |
ie兼容到了 ie8 | ie 兼容 ie10 |
锚点问题
<div>
<a name="mao">顶部</a>
<div class="mao"></div>
<a href="#mao">跳转顶部</a>
</div>
hash模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zT6jTLuZ-1684058312708)(Img/image-20221207133332543.png)]
history 模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aLZgxQ4E-1684058312708)(Img/image-20221207133430052.png)]
hash 和 history 共有的方法
history.back()
history.forward()
history.go(number)
history.state:History 堆栈最上层的状态值[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XLgNziL3-1684058312709)(Img/image-20221207110346608.png)]
widow.history 执向History 对象[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8vLXcjZN-1684058312709)(Img/image-20221207110639062.png)]
hashchange事件
// window.onhashchange 写在 router index.js 文件中生效 可以监听到每次hash值的变化
window.addEventListener('hashchange',()=>{ //监听到的是浏览器的前进后退事件,自己写的按钮跳转时监听不到
console.log('hash值',window.location.hash);
})
// 监听到hash值的变化
// event.oldURL event.newURL 监听到的是整个url
window.addEventListener('hashchange',(event) => {
console.log('old',event.oldURL);
console.log('new',event.newURL);
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UXqSqlyR-1684058312710)(Img/image-20221207093935174.png)]
hash 模式 不会将hash 值发送给 服务器 ,自己可以配置路由信息
history 模式 会将 路由信息发送给 服务器
history.pushState(obj,title,url)
object:是一个对象,通过 pushState 方法可以将该对象内容传递到新页面中。如果不需要这个对象,此处可以填 null。
title:指标题,几乎没有浏览器支持该参数,传一个空字符串比较安全。
url:新的网址,必须与当前页面处在同一个域。不指定的话则为当前的路径,如果设置了一个跨域网址,则会报错
add(){
history.pushState(null,null,'http://localhost:8081/history')
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IYifNQPE-1684058312710)(Img/image-20221207111915381.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BHAJVbmr-1684058312711)(Img/image-20221206153649393.png)]
五 路由懒加载
当加载路由文件时,首先要加载所有引入 的路由组件,这样会影响页面的加载速度,会延长首页的白屏时间
解决方法:路由懒加载,只有在需要这个路由时,才会加载这一部分的js 代码 就是 按需加载
写法1:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
写法2:
component:resolve => require(['@/pages/task'],resolve)
六input 输入框
获取 input 的节点后,用
this.$ref
七vuex
State 存放数据
Getter 相当于state的计算属性
Mutation 同步方法
调用 mutation 方法
this.$store.commit('increment')
Action 异步方法
异步
的mutation操作,不过提交的是mutation
。
actions: {
increment ({ commit,state,getters }) {
commit('increment')
}
在action commit(同步方法名称)
就可以调用同步方法
script 中触发
this.$store.dispatch
参数commit
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
date:'2023-02-03'
},
getters: {
},
mutations: {
LogDat(state){
console.log(state.date);
}
},
actions: {
actionsTest({commit}){
commit('LogDat') // 直接调用mutations中的方法
console.log(commit);
}
},
modules: {
}
})
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iHUuSgwh-1684058312711)(./Img/image-20230203101523921.png)]
Module 模块
// window.onhashchange 写在 router index.js 文件中生效 可以监听到每次hash值的变化
window.addEventListener('hashchange',()=>{ //监听到的是浏览器的前进后退事件,自己写的按钮跳转时监听不到
console.log('hash值',window.location.hash);
})
// 监听到hash值的变化
// event.oldURL event.newURL 监听到的是整个url
window.addEventListener('hashchange',(event) => {
console.log('old',event.oldURL);
console.log('new',event.newURL);
})
[外链图片转存中…(img-UXqSqlyR-1684058312710)]
hash 模式 不会将hash 值发送给 服务器 ,自己可以配置路由信息
history 模式 会将 路由信息发送给 服务器
history.pushState(obj,title,url)
object:是一个对象,通过 pushState 方法可以将该对象内容传递到新页面中。如果不需要这个对象,此处可以填 null。
title:指标题,几乎没有浏览器支持该参数,传一个空字符串比较安全。
url:新的网址,必须与当前页面处在同一个域。不指定的话则为当前的路径,如果设置了一个跨域网址,则会报错
add(){
history.pushState(null,null,'http://localhost:8081/history')
}
[外链图片转存中…(img-IYifNQPE-1684058312710)]
[外链图片转存中…(img-BHAJVbmr-1684058312711)]
五 路由懒加载
当加载路由文件时,首先要加载所有引入 的路由组件,这样会影响页面的加载速度,会延长首页的白屏时间
解决方法:路由懒加载,只有在需要这个路由时,才会加载这一部分的js 代码 就是 按需加载
写法1:
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
写法2:
component:resolve => require(['@/pages/task'],resolve)
六input 输入框
获取 input 的节点后,用
this.$ref
七vuex
State 存放数据
Getter 相当于state的计算属性
Mutation 同步方法
调用 mutation 方法
this.$store.commit('increment')
Action 异步方法
异步
的mutation操作,不过提交的是mutation
。
actions: {
increment ({ commit,state,getters }) {
commit('increment')
}
在action commit(同步方法名称)
就可以调用同步方法
script 中触发
this.$store.dispatch
参数commit
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
date:'2023-02-03'
},
getters: {
},
mutations: {
LogDat(state){
console.log(state.date);
}
},
actions: {
actionsTest({commit}){
commit('LogDat') // 直接调用mutations中的方法
console.log(commit);
}
},
modules: {
}
})
[外链图片转存中…(img-iHUuSgwh-1684058312711)]