年度总结+学习打卡
一些小知识
word技巧
选择题挖空
文字无填充+黑色下划线
获得单字拼音
拼音指南+只保留文本粘贴
两端对齐英文排版满行
分散对齐占满所在的行
Excel技巧
公式视图CTRL+` 批量填充CTRL+Enter 单表数据量约为百万条
单元格格式匹配顺序为 正数格式;负数格式;零值格式;文本格式 用[]表示格式或条件 占位符有: 数字0/#/? 字符@
换行输入ALT+Enter
利用数字拖拽+单元格格式生成学号
也可数字拖拽+TEXT函数生成学号 (数值精度15位,写身份证会进位,重做) 写函数在识别到函数时按F1 可查看公式具体内容
PPT技巧
选择窗格对象起名
陀螺旋+触发器可以做抽奖
OKPlusPPT插件有批量工具,PPT效率插件
算法
大致学习了以下的内容:
-
数组
- 排序,查找,求区间,统计,过滤
-
字符串
- 遍历,拼接,分割,查找,匹配,比较,格式转换
-
栈&队列
- 先进先出/先进后出
-
集合和哈希表
- 记录存在/记录状态
-
二叉树
- 查找/遍历
-
回溯
- 回溯是迭代的,还可以做剪枝 直接for嵌套就不好处理
-
贪心
- 积累局部最优得最优
-
动态规划
- 存储子问题的解,通过迭代,压缩到多项式时间 避免全量计算 for的效率比递归高,所以很多时候优于回溯
选择器
权重
| 选择器 | 权重 |
|---|---|
| 继承/通配符/后代( )/子(>)/并集(,) | 0,0,0,0 |
| 元素选择器/伪元素选择器 | 0,0,0,1 |
| 类选择器/伪类选择器/属性选择器 | 0,0,1,0 |
| ID选择器 | 0,1,0,0 |
| 行内样式style="" | 1,0,0,0 |
| !important重要的 | ∞无穷大 |
层叠性
链接伪类选择器
| 选择器 | 说明 |
|---|---|
| a:link | 选择未被访问的链接 |
| a:visited | 选择已被访问的链接 |
| a:hover | 选择鼠标悬停时的链接 |
| a:active | 选择活动(鼠标按下未松开)的链接 |
为了防止被覆盖按照LVHA的顺序 love hate
除了链接伪类,还有表单伪类focus等
属性选择器
- E[att="val"]根据某属性值来进行选择
- E[att^="val"]根据属性值开头来进行选择
- E[att$="val"]根据属性值结尾来进行选择
- E[att*="val"]根据属性子串来进行选择
结构伪类选择器
- E:first-child(先把每个孩子都排列一个序号,在根据序号判断是否为指定元素)
- E:last-child
- E:nth-child(n) 第n个子元素
- nth-child选择器()里可以是数字,也可以是公式和关键字(even(偶数)、odd(奇数))
- 公式1:E:nth-child(n) 选择所有的孩子
- 公式other: 2n(偶数)、2n+1(奇数)、5n(5的倍数)、n+5(第5个到最后)、-n+5(前5个)
- E:first-of-type(会看指定元素,再排序)
- E:last-of-type
- E:nth-of-type(n)
伪元素选择器(属于行内元素,但在HTML中找不到)
- ::before
- ::after
鼠标坐标计算
-
pageX,pageY(mousemove的事件触发时鼠标在页面中的坐标)
-
offsetTop+offsetLeft属性或getBoundingClientRect()方法(相对于视口的坐标)
-
e.pageX - getBoundingClientRect().left-document.documentElement.scrollLefte.pageY - getBoundingClientRect().top-document.documentElement.scrollTop
好处是不受父元素定位影响,但要计算滚动距离
垃圾回收机制算法
引用计数法
IE采用"内存不再使用"就回收的思想,==追踪记录被引用的次数==,引用次数为0时回收
通过让引用类型对象的引用为空,如arr = null ,来回收
▼js复制代码function fun(){ let o1 = {} let o2 = {} o1.a = o2 o2.a = o1 return '引用计数无法回收' } fun()
嵌套引用不回收,因为堆里面的数值相互引用了,我们只能改地址到数值的引用,所以就导致了内存泄漏...
标记清除法
现代的浏览器采用"无法到达"就回收的思想,从根部(即js的全局变量)出发扫描内存对象,凡是能到达就还需要用,无法触及到的对象被标记为不再使用,稍后回收.
闭包
闭包是指使用了外层非全局变量的函数,特征是变量提升
即函数引用和外层变量一起提升到访问闭包函数的那一级作用域
闭包其实是利用了垃圾回收机制,有内存泄漏的风险
箭头函数与立即执行
参数列表只有一个参数时箭头函数可以写作argument1 => {}
函数体只有一个语句时还能简化,像() => console.log(1)
如果仅有的一句是return可以在省略{}的情况下再省略return直接写值() => 1+1
对于匿名函数,箭头函数() => {} 比funcition () {}简略一些,而且箭头函数没有自己的this,只会隔离代码防止命名冲突
立即执行函数:
(function(c){ return c})('参数')
(function(c){ return c}('参数'))
(c => ({ name: c }))('刘德华') //立即执行返回对象
解构赋值
左值直接写成和数组或对象一致的情况可以进行解构赋值
const [a,[b,c]] = [1,[2,3]] //定义三个变量,分别赋值为1,2,3
数组常用方法
语法:
| 方法 | 作用 | 说明 |
|---|---|---|
| forEach(回调函数(item,index,array)) | 遍历 | 不返回数组,查找数组元素 |
| filter(回调函数(item,index,array)) | 过滤 | 返回数组,筛选满足条件的数组 |
| map(回调函数(item,index,array)) | 映射 | 返回数组,返回处理后的数组 |
| reduce((非迭代)回调函数(prev,current),起始值) | 累计计算 | 返回累计处理的结果,经常用于求和(再加上初始值) |
| join(分隔符=',') | 拼接 | |
| find(回调函数) | 查找 | 返回第一个匹配的值,没有返回undefined |
| every(回调函数) | 检测所有 | 都符合返回true否则false |
| some(回调函数) | 检测存在 | 有符号返回true否则false |
| concat(其他数组) | 合并数组 | 返回新数组 |
| sort(compareFn),默认数组元素会被转换为字符串,然后根据每个字符的 Unicode 码位值进行排序。 | 排序 | 返回数组 |
| splice(start, deleteCount, item1, item2, /* …, */ itemN) | 删除\替换原数组单元 | 返回删掉的数组 |
字符串常用方法
语法:
| 实例方法 | 作用 |
|---|---|
| split(separator) | 字符串拆分成数组 |
| substring(startIndex,[endIndex]) | 截取子串(不包含结束位置的字符) |
| startsWith(searchString,[startPosition=0]) | 判断开始是否是searchString |
| includes(string,[index=0]) | 包含 |
| toUpperCase | 转大写 |
| toLowerCase | 转小写 |
| indexOf | 查找索引 |
| endsWith(searchString, [endPosition=this.length-1]) | 判断结束是否是searchString |
| replace | 替换,支持正则匹配 |
| match | 查找,支持正则匹配 |
对象原型和原型对象
使用instanceof检测构造函数的prototype属性是否出现在某个实例对象的原型链上
构造函数new实例,prototype原型对象
实例对象可以通过__proto__属性获得对象的原型
原型对象和对象原型指向同一个对象,只是概念用途存在差异
__proto__主要用于运行时的属性和方法查找
prototype主要用于新对象共享原型对象的属性和方法,这样可以节省内存,提高代码的复用性
深拷贝模板
▼js复制代码function deepClone(source) { if (typeof source !== 'object' || source == null) { return source; } const target = Array.isArray(source) ? [] : {}; for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { if (typeof source[key] === 'object' && source[key] !== null) { target[key] = deepClone(source[key]); } else { target[key] = source[key]; } } } return target; }
异常捕获语法
▼js复制代码try { // 要执行的语句 // 这里可以放置可能会抛出异常的代码,例如: // let result = someFunctionThatMightThrowError(); } catch (exceptionVar) { // 异常处理 // 当 try 块中的代码抛出异常时,程序将跳转到这里,exceptionVar 包含异常信息 // 可以根据 exceptionVar 的类型和信息进行相应的处理,例如: // if (exceptionVar instanceof SomeErrorType) { // console.error('发生了某种类型的错误:', exceptionVar.message); // } else { // console.error('发生了其他错误:', exceptionVar.message); // } } finally { // 无论是否报错都执行的退出前语句,哪怕 throw 抛出异常 // 这里通常用于资源清理,例如关闭文件、释放连接等操作,例如: // if (file) { // file.close(); // } }
防抖截流
防抖是触发中打断重新触发
实现方式:
- lodash库处理防抖
_.debounce(fun,时间) - 手写防抖函数
▼js复制代码function debounce(fun,t){ let timer return function(){ if(timer) clearTimeout(timer) timer = setTimeout(fun,t) } }
节流是触发中不再重复触发
实现方式:
- lodash库处理节流
_.throttle(fun,时间) - 手写节流函数
▼js复制代码function throttle(fn,t){ let timer return function(){ if(!timer){ timer = setTimeout{function(){ fn() timer = null//(使用clearTimeout()不会清除timer的值) },t} } } }
视口标签与二倍图
视口标签可以控制页面的显示缩放和自适应调整
比如**initial-scale=1.0** 加**maximum-scale=1.0加minimum-scale=1.0**不让用户缩放
**width=device-width**视口宽度设置为设备屏幕宽度
手机等设备会用两个以上物理像素显示一个像素,想要图片不糊,需要提前准备二倍图,这样先缩小再放大,不会影响显示
flex布局
设置display:flex
justify-content: space-around
6个属性是对父元素设置的
-
flex-direction(设置主轴方向(默认是row,向右为正方向(row-reverse翻转可以让元素从右到左,向左为正方向),垂直方向是侧轴。可以设置为column,默认向下是正方向))
-
flex-wrap(默认情况下flex里不换行,项目都排在一条线(轴线)上,加元素会缩小所有子元素)
wrap(装不开就换行)nowrap(默认值,不换行)
-
flex-flow(设置主轴方向与设置换行合写)
-
justify-content(使用前请确认主轴是哪个)
属性值 说明 flex-start 默认值 从头部开始 如果主轴是x轴,则从左向右 flex-end 从尾部开始排列(==顺序不变==) center 在主轴居中对齐(如果主轴是x轴则水平居中) space-around 平分==剩余==空间(左右边距相等,即两边会少一块边距) space-between 先两边贴边 再平分剩余空间(重要) -
align-items(侧轴对齐,只适用于单行(没有flex-wrap属性))
属性值 说明 flex-start 默认值 从侧轴头部开始排列 flex-end 从尾部开始排列(==顺序不变==) center 在侧轴居中显示 stretch 拉伸(默认值,若子元素有高度则无效,否则占满) -
align-content(试用于子项换行的情况)
属性值 说明 flex-start 默认值 从侧轴头部开始排列 flex-end 从尾部开始排列(==顺序不变==) center 在侧轴居中显示 space-around 在侧轴平分剩余空间 space-between 先两边贴边 再平分剩余空间 stretch 拉伸(子项元素平分高度)
flex属性定义子项分配多少份==剩余空间==(左右固定,中间分配唯一的剩余空间,就可以实现所谓圣杯布局或双飞翼布局的效果)
flex: num
align-self(控制子项自己在侧轴上的对齐方式)
flex可以套娃
渐变色
线性渐变:background: linear-gradient(起始方向,颜色1,颜色2,...);
有如下几种写法:
background: -webkit-linear-gradient(red,blue);(默认是从上往下)
background: -webkit-linear-gradient(left,red,blue);
background: -webkit-linear-gradient(left top,red,blue);
没设置宽度时flex垂直分布改align-items则不会默认填满每个水平宽度
媒体查询
基本语法
media-type:all:适用于所有设备类型。screen:主要用于电脑屏幕、平板电脑、智能手机等屏幕显示设备。print:用于打印机和打印预览。speech:用于屏幕阅读器等语音合成器。
media-feature:width:视口的宽度。
min-width和max-width:视口的最小和最大宽度。height、min-height和max-height:视口的高度及最小和最大高度。orientation:设备的方向,值可以是portrait(纵向)或landscape(横向)。resolution:设备的分辨率。
可以使用and和not作为逻辑操作符控制媒体查询
使用only 指定特定媒体类型
css媒体查询
▼css复制代码@media screen and (min-width: 1200px) { header { height: 100px; } } @media screen and (min-width: 768px) and (max-width: 1199px) { header { height: 80px; } } @media screen and (max-width: 767px) { header { height: 60px; } }
外部样式表中的媒体查询
▼html复制代码<link rel="stylesheet" href="large.css" media="screen and (min-width: 1200px)"> <link rel="stylesheet" href="medium.css" media="screen and (min-width: 768px) and (max-width: 1199px)"> <link rel="stylesheet" href="small.css" media="screen and (max-width: 767px)">
less语法
一、Less 基础概念
- Less 是一种 CSS 预处理器,它扩展了 CSS 的功能,最终会编译为 CSS 代码,使样式表更具可维护性和扩展性。
二、变量
- 声明:使用
@变量名: 值;来定义变量,例如:@primary-color: #333;。 - 使用:在样式中使用
@变量名来引用变量,如color: @primary-color;。变量可用于存储颜色、尺寸、字体等,提高代码复用性和可维护性。
三、嵌套
- 基本嵌套:将子元素的样式嵌套在父元素样式内部,增强代码结构的逻辑性。
▼less复制代码nav { ul { margin: 0; li { list-style: none; } } }
- 伪类和伪元素嵌套:在嵌套中使用
&来表示父元素,以处理伪类和伪元素。
▼less复制代码a { color: blue; &:hover { color: red; } &:before { content: ''; } }
四、混合(Mixins)(嵌套)
- 声明:使用类名或 ID 来定义混合,可包含一组样式,可带参数。
▼less复制代码.border-radius(@radius) { border-radius: @radius; }
- 使用:将混合应用到元素上,可传递参数。
▼less复制代码.button { .border-radius(5px); }
- 不带参数的混合:可以直接引用,像调用函数一样,实现代码复用。
▼less复制代码.border { border: 1px solid black; } .box { .border; }
五、函数
- Less 提供了内置函数,如
lighten(@color, 10%)可将颜色变亮,darken(@color, 10%)可将颜色变暗。
▼less复制代码@base-color: #f06; .button { color: lighten(@base-color, 20%); }
- 自定义函数:使用 Guard 表达式和模式匹配,可以实现自定义函数功能。
▼less复制代码.square(@size) when (isnumber(@size)) { width: @size; height: @size; }
六、运算
- 支持基本的算术运算,如加、减、乘、除。注意运算符两边要有空格,单位遵循 CSS 规则。
▼less复制代码@width: 100px; @padding: 20px; .container { width: @width - @padding; }
- 颜色运算:可对颜色进行加、减、混合等操作。
▼less复制代码@color: #444; .button { background-color: @color + #111; }
七、继承
- 使用
:extend()关键字实现继承,减少代码重复。
▼less复制代码.primary-button { background-color: blue; } .secondary-button { &:extend(.primary-button); color: white; }
八、导入
- 使用
@import "文件名";导入其他 Less 或 CSS 文件,可导入多次,Less 会自动合并。
▼less复制代码@import "variables"; @import "mixins";
九、条件判断
- 使用
when关键字进行条件判断,结合 Guard 表达式。
▼less复制代码.border-radius(@radius) when (@radius > 0) { border-radius: @radius; }
十、循环
- 通过递归混合和 Guard 表达式可实现循环功能。
▼less复制代码.generate-columns(@n) when (@n > 0) { .column-@{n} { width: (@n * 100% / 12); } .generate-columns(@n - 1); } .generate-columns(12);
十一、命名空间和访问器
- 创建命名空间:使用
#命名空间名包裹一组混合,使用时需通过#命名空间名.混合名访问。
▼less复制代码#utils { .center() { margin: auto; } } .container { #utils.center(); }
Less 的优势在于其强大的变量、混合、函数、继承等功能,能够帮助你编写更简洁、灵活、易于维护的样式表,同时也支持各种高级逻辑,如条件判断和循环,通过编译为 CSS 保证了在浏览器中的兼容性。
Bootstrap布局
提供了一些使用的插件和布局
axios语法
实例配置
▼js复制代码const instance = axios.create({ baseURL: 'https://api.example.com', timeout: 1000, headers: { 'Content-Type': 'application/json' } }); instance.get('/data') .then(response => { console.log(response.data); }) .catch(error => { console.error(error); });
拦截器
▼js复制代码instance.interceptors.request.use( config => { // 在发送请求之前做些什么,如添加 token config.headers.Authorization = 'Bearer token'; return config; }, error => { // 对请求错误做些什么 return Promise.reject(error); } ); instance.interceptors.response.use( response => { // 对响应数据做点什么,如处理错误码 if (response.status === 200) { return response.data; } return Promise.reject(response); }, error => { // 对响应错误做点什么,如处理错误信息 console.error(error); return Promise.reject(error); } );
可以使用 axios.all 发送多个并发请求
可以使用 Axios 的 CancelToken 来取消请求
原生XHR
使用XMLHttpRequest的步骤:
- 创建XMLHttpRequest对象
- 配置请求方法和请求url地址
- 监听loadend事件,接收响应结果
- 发起请求
示例:
▼js复制代码const xhr = new XMLHttpRequest() xhr.open('get', 'http://hmajax.itheima.net/api/city?pname=辽宁省') xhr.addEventListener('loadend', e => document.querySelector('.my-p').innerHTML = JSON.parse(e.target.response).list.join('<br>')) xhr.send()
▼js复制代码function sendRequest(url, method, data = null, token = null, timeout = 5000) { return new Promise((resolve, reject) => { // 1. 创建对象 let xhr = new XMLHttpRequest(); // 2. 配置请求 xhr.open(method, url, true); // 设置超时时间(毫秒) xhr.timeout = timeout; // 设置请求头 if (token) { xhr.setRequestHeader('Authorization', `Bearer ${token}`); } if (data) { xhr.setRequestHeader('Content-Type', 'application/json'); } // 3. 监听事件,接收响应结果 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { // 请求成功 resolve(xhr.responseText); } else { // 请求失败,但请求已完成 reject(new Error(`Request failed with status ${xhr.status}: ${xhr.statusText}`)); } }; xhr.onerror = function() { // 网络错误,请求无法完成 reject(new Error('Network error occurred')); }; xhr.ontimeout = function() { // 请求超时 reject(new Error('Request timed out')); }; xhr.onabort = function() { // 请求被中止 reject(new Error('Request aborted')); }; // 4. 发起请求 if (data) { xhr.send(JSON.stringify(data)); } else { xhr.send(); } }); }
Promise
Promise 对象表示异步操作==最终状态==(完成或失败)以及其==结果值==。
▼js复制代码//1.创建Promise对象并传递参数 const p = new Promise((resolve,reject)=>{ //2.执行异步任务-并传递结果 //根据自定义的判断分支,可以返回两种调用 //成功调用: resolve(值)触发then()执行 //失败调用: reject(值) 触发catch()执行 //两种调用都不会直接返回,但是它们之间会有冲突,先调用的那一个有效(先占先得) }) //3.接受结果 p.then(result=>{ //进行resolve调用时这里拿到参数resolve()里的值 }).catch(error=>{ //进行reject调用时,这里拿到参数reject() 里的值 })
简易版axios
▼js复制代码function myAxios(configObj) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() // let params = '' let data = configObj.data || null if (configObj.params) { configObj.url += '?' + new URLSearchParams(configObj.params).toString() // const obj = } xhr.open(configObj.method || 'GET', configObj.url) if (data) { if (data instanceof FormData) { //手动处理 multipart/form-data 是非常复杂的,需要处理boundary并手动构建表单数据,所以什么也不需要做, //浏览器会自动处理请求头 } else if (data instanceof Object) { console.log(1) xhr.setRequestHeader('Content-Type', 'application/json') data = JSON.stringify(data) console.log(data) } } xhr.addEventListener('loadend', e => { if (/^2/.test(xhr.status)) { resolve(JSON.parse(xhr.response)) } else { reject(new Error(xhr.response)) } }) xhr.send(data) }) }
Promise可以实现链式调用,避免回调函数地狱问题
有async和await语法糖
事件循环
宏任务通常是由浏览器环境提供的异步任务。常见的宏任务有setTimeout、setInterval、setImmediate(仅在 Node.js 中有)、I/O 操作、UI 渲染等。
微任务是由 JavaScript 引擎自身管理的异步任务。常见的微任务有Promise.then、process.nextTick(仅在 Node.js 中有)、MutationObserver等。
事件循环是一种机制,它持续检查调用栈是否为空,为空时先执行微任务队列直到清空,再从宏任务队列中取出一个宏任务放入调用栈执行,如此循环,以实现 JavaScript 的异步执行。
wang Editor
一个富文本编辑器插件
Node.js模块
一、HTTP 模块
▼js复制代码const http = require('http') // 创建服务器 const server = http.createServer((req, res) => { if (req.method === 'GET') { // 处理 GET 请求 res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end('This is a GET request') } else if (req.method === 'POST') { let body = '' // 接收 POST 请求的数据 req.on('data', (chunk) => { body += chunk.toString() }) req.on('end', () => { // 处理 POST 请求的数据 res.writeHead(200, { 'Content-Type': 'text/plain' }) res.end(`This is a POST request with body: ${body}`) }) } else { // 处理其他请求方法 res.writeHead(405, { 'Content-Type': 'text/plain' }) res.end('Method Not Allowed') } }) // 监听端口 server.listen(3000, () => { console.log('Server is running on port 3000') })
解释:
- 首先使用
http.createServer创建一个 HTTP 服务器,回调函数接收req(请求)和res(响应)对象。 - 根据
req.method判断请求方法,若是GET请求,设置响应头并返回相应内容;若是POST请求,通过req.on('data')监听数据传输,将数据累加到body中,在req.on('end')时处理完整的数据;对于其他请求方法,返回 405 错误。 - 使用
server.listen监听 3000 端口,并在监听成功时输出日志。
二、Fs 模块
▼js复制代码const fs = require('fs') // 同步读取文件 try { const data = fs.readFileSync('example.txt', 'utf8') console.log(data) } catch (err) { console.error(err) } // 异步读取文件 fs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error(err) return } console.log(data) }) // 写入文件(异步) fs.writeFile('output.txt', 'Hello, World!', (err) => { if (err) { console.error(err) return } console.log('File has been written successfully') }) // 使用流进行文件读取 const readStream = fs.createReadStream('example.txt') readStream.on('data', (chunk) => { console.log(chunk.toString()) }) readStream.on('end', () => { console.log('File reading completed') }) // 使用流进行文件写入 const writeStream = fs.createWriteStream('output.txt') writeStream.write('This is a streamed write.') writeStream.end() writeStream.on('finish', () => { console.log('File has been written using stream') })
解释:
fs.readFileSync同步读取文件,需处理可能的异常。fs.readFile异步读取文件,通过回调处理结果或错误。fs.writeFile异步写入文件,根据回调处理错误。fs.createReadStream创建文件读取流,通过on('data')监听数据块,on('end')表示读取完成。fs.createWriteStream创建文件写入流,使用write方法写入数据,end方法结束写入,on('finish')表示写入完成。
三、Path 模块
▼js复制代码const path = require('path') // 路径拼接 const fullPath = path.join(__dirname, 'subfolder', 'example.txt') console.log(fullPath) // 解析路径 const parsedPath = path.parse(fullPath) console.log(parsedPath) // 获取路径分隔符 const separator = path.sep console.log(separator)
解释:
path.join将当前目录(__dirname)和subfolder及example.txt拼接成完整路径。path.parse解析路径,返回包含根目录、目录、文件名等信息的对象。path.sep获取系统的路径分隔符,在不同操作系统下不同(如 Windows 是\,Unix 是/)。
四、Url 模块
▼js复制代码const url = require('url') const urlString = 'http://example.com:8080/path?query=string&key=value' const urlObj = url.parse(urlString, true) console.log(urlObj.protocol) // 协议 console.log(urlObj.host) // 主机和端口 console.log(urlObj.pathname) // 路径 console.log(urlObj.query) // 查询参数对象 // 格式化 URL const formattedUrl = url.format({ protocol: 'http', hostname: 'example.com', port: 8080, pathname: '/path', query: { query: 'string', key: 'value' } }) console.log(formattedUrl)
解释:
url.parse将 URL 字符串解析为对象,true表示将查询参数解析为对象。- 可通过
urlObj的属性获取 URL 的各个部分,如协议、主机、路径、查询参数等。 url.format将对象格式化为 URL 字符串。
五、Buffer 模块
▼js复制代码const buffer = Buffer.from('Hello, Buffer') console.log(buffer.toString()) const buffer2 = Buffer.alloc(10) // 创建一个长度为 10 的空缓冲区 buffer2.write('Node.js') console.log(buffer2.toString()) const buffer3 = Buffer.allocUnsafe(10) // 创建一个未初始化的长度为 10 的缓冲区 buffer3.write('Buffer', 0, 6) console.log(buffer3.toString())
解释:
Buffer.from从字符串创建缓冲区并转换为字符串。Buffer.alloc创建指定长度的已初始化缓冲区,可使用write方法写入数据。Buffer.allocUnsafe创建未初始化缓冲区,需注意可能包含旧数据,使用时要谨慎,使用write方法可在指定位置写入数据。
六、Events 模块
▼js复制代码const EventEmitter = require('events') const myEmitter = new EventEmitter() // 定义事件监听器 myEmitter.on('customEvent', (arg1, arg2) => { console.log(`Event occurred with arguments: ${arg1} and ${arg2}`) }) // 触发事件 myEmitter.emit('customEvent', 'Hello', 'World')
解释:
- 使用
EventEmitter类创建一个事件发射器实例。 on方法添加事件监听器,接收事件名和回调函数。emit方法触发事件,并可传递参数,触发时调用相应的监听器函数。
CommonJS与ECMAScript
CommonJS标准
一般应用在Node.js项目环境中
需求:定义utils.js模块,封装基地址和求数组总和的函数
使用module.exports = {}导出文件
▼js复制代码const baseURL = 'http://hmajax.itheima.net'//基地址常量 const getArraySum = arr => arr.reduce((sum,val) => sum += val , 0)//求和函数 module.exports = { 对外属性名1:baseURL,//此处自定义对外暴露的属性 对外属性名2:getArraySum }//向外导出
导入: require('模块名或路径')
- 内置模块:直接写名字
- 自定义模块:写模块文件路径
ECMAScript标准
一般应用在前端工程化项目中
默认导出和导入
默认导出: export default 暴露模块对象
▼js复制代码export default{ //此处自定义对外暴露的属性 }
导入语法:import 变量名 from '模块名或路径'
注意:Node.js默认支持 CommonJS标准语法,在运行模块所在文件夹新建package.json文件,并设置{"type" : "module"}(默认值是commonjs)
Nodejs项目配置
命名导出和导入
命名导出: export 修饰==定义语句==(例如 const baseURL = "http://any")
导入: import {同名变量} from '模块名或路径'
如何选择:
按需加载,使用命名导出和导入(有点类似于对象解构,只声明需要的属性导入)
全部加载,使用默认导出和导入
其他
之后学习了Webpack,Git,Vue,React,echart,TS,小程序
见过的优化有包体积分析,分割代码块,异步懒加载,CDN分发三方包
学习了各种路由(Vue Router,React Router)和状态管理
其实大的收获可能就是经验加一些琐碎的模板(以后相关内容搜下笔记),如图:
下面放一个react模板好了,这算是本人现有笔记中比较完整的模板了
项目初始化
使用vite创建项目
▼bash复制代码yarn create vite react template --template react
vite自动打开浏览器+端口配置
▼js复制代码//vite.config.js ... server: { host: '0.0.0.0', port: 8989, // 是否开启 https https: false, }, //package.json命令 "dev": "vite --open",
运行启动,无误
清理目录
删除样式和图标,App.js留个架子,index.html中清除图标引用,main.jsx中清除样式引用,重启无误
最终路径如下:
▼bash复制代码│... │ └─src │ App.jsx │ main.jsx │ ├─api ├─assets ├─components ├─page │ └─NotFound │ index.jsx │ NotFound.css │ ├─router │ index.jsx │ ├─store │ │ index.jsx │ │ │ └─modules │ counter.jsx │ └─utils index.jsx request.jsx
配置别名路径
路径解析配置:
▼js复制代码//如果没有传入 path 片段,则 path.resolve() 将返回当前工作目录的绝对路径。 import { resolve } from 'path' const __dirname = resolve(); /**这样写也可以: * * import path from 'path'; * import { fileURLToPath } from 'url'; * const __dirname = path.dirname(fileURLToPath(import.meta.url)); * */ resolve: { // 设置文件./src路径为 @ alias: [ { find: '@', replacement: resolve(__dirname, './src') } ] }
联想路径配置:
▼json复制代码//jsconfig.json { "compilerOptions": { "baseUrl": "./", "paths": { "@/*": [ "src/*" ] } } }
运行无误
VSCode配置setting
▼json复制代码{ //主题 "workbench.colorTheme": "One Dark Pro", "workbench.iconTheme": "vscode-icons", //保存代码时自动格式化(便于使用prettier插件) "editor.formatOnSave": false, // 删除文件时不弹出确认对话框 "explorer.confirmDelete": false, //默认终端和浏览器 "terminal.integrated.defaultProfile.windows": "Command Prompt", "open-in-browser.default": "Chrome", //使用空格,默认大小为2,自动换行,自动闭合括号 "editor.insertSpaces": true, "editor.tabSize": 2, "editor.wordWrap": "on", "editor.autoClosingBrackets": "always", //关闭JS代码校验 当保存的时候,使用eslint自动帮助我们修复错误 "editor.codeActionsOnSave": { "source.fixAll": "always" }, "javascript.validate.enable": false, //volar 是 vue3 的配套,vetur 是 vue2 的配套,这里用Vue3 // "[vue]": { // "editor.defaultFormatter": "Vue.volar" //和eslint校验冲突,应关闭 // }, // 使 JavaScript 支持 Emmet 开启Emmet补全 "emmet.includeLanguages": { "javascript": "javascriptreact" }, "emmet.triggerExpansionOnTab": true, // less 编译输出目录配置 "less.compile": { "out": "${workspaceRoot}\\css\\" }, //使用prettier格式化代码 // "editor.defaultFormatter": "esbenp.prettier-vscode" //有保存时自动修复,没必要 }
配置代码校验
EditorConfig:(跨编辑器编码风格统一)
对于VSCode,需开启EditorConfig for VS Code
▼js复制代码// .editorconfig root = true [*] charset = utf-8 indent_style = space indent_size =2 end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true //另起一行结束 [*.md] max_line_length = off trim_trailing_whitespace = false
prettier单独使用:(代码自动格式化工具)
对于VSCode,三步走
开启 Prettier - Code formatter ,
Editor: Default Formatter 设置为 Prettier - Code formatter
Format On Save √
▼js复制代码// .prettierrc { "useTabs": false, "tabWidth": 2, "printWidth": 80, "singleQuote": true, "trailingComma": "none", //尾随逗号 "semi": false }
使用命令格式化:
不用插件,额外配置以下内容
▼js复制代码//package.json "prettier": "prettier --write ." //.prettierignore node_modules build .husky *.svg *.sh .local public
ESlint:(代码检查工具)
使用prettier进行风格校验,prettier只设置配置项即可
如果项目空空如也,可以先执行npx eslint --init
安装
▼bash复制代码yarn add eslint-plugin-prettier eslint-config-prettier
配置
▼js复制代码import js from '@eslint/js' import globals from 'globals' import react from 'eslint-plugin-react' import reactHooks from 'eslint-plugin-react-hooks' import reactRefresh from 'eslint-plugin-react-refresh' import eslintConfigPrettier from 'eslint-config-prettier' // 用于避免 ESLint 与 Prettier 的冲突 import prettier from 'eslint-plugin-prettier' // 用于将 Prettier 作为 ESLint 规则执行 export default [ { ignores: ['**/node_modules/', '**/.vscode/', '**/.husky/', 'dist'] }, { files: ['**/*.{js,jsx}'], languageOptions: { ecmaVersion: 2020, globals: globals.browser, parserOptions: { ecmaVersion: 'latest', ecmaFeatures: { jsx: true }, sourceType: 'module' } }, settings: { react: { version: '18.3' } }, plugins: { react, 'react-hooks': reactHooks, 'react-refresh': reactRefresh, prettier // 启用 Prettier 插件 }, rules: { // 添加默认的推荐规则 ...js.configs.recommended.rules, // React 相关的推荐规则 ...react.configs.recommended.rules, // React JSX 运行时相关的规则 ...react.configs['jsx-runtime'].rules, // React Hooks 推荐规则 ...reactHooks.configs.recommended.rules, // 关闭 "jsx-no-target-blank"(允许不加 rel="noopener noreferrer") // 'react/jsx-no-target-blank': 'off', // 禁止不必要的赋值 'no-useless-assignment': 'error', // React Refresh 只允许导出组件 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true } ], // Prettier 格式化规则,强制执行 Prettier 风格 'prettier/prettier': 'error' // 这里启用 Prettier 的代码风格检查 } }, // 通过直接添加 eslint-config-prettier 来禁用可能的冲突规则 eslintConfigPrettier // 禁用与 Prettier 冲突的 ESLint 规则 ]
使用Husky工具管理版本提交
安装
▼bash复制代码yarn add husky -D npx husky init yarn add lint-staged -D #pre-commit修改 # yarn lint-staged
▼js复制代码#package.json配置 // 命令 "lint": "eslint . --fix", "lint-staged": "lint-staged", // 配置项 "lint-staged": { "*.{js,ts,jsx,tsx,vue}": [ ////不要漏掉jsx "eslint --fix" ] }
报错
- Current directory is not a git directory!(初始化)
- No staged files found. (提交暂存区)
- No valid configuration found (配置项)
配置ReactRouter
安装依赖
▼bash复制代码yarn add react-router-dom@6 history@5
模板代码
▼js复制代码//@/router/index.jsx import App from '@/App' //很可能用不上,首页一般单独写layout组件,先占个位 import NotFound from '@/page/NotFound' //需要额外准备 import { createBrowserRouter } from 'react-router-dom' const router = createBrowserRouter([ { path: '/', element: <App /> }, { path: '*', element: <NotFound /> } ]) export default router //main.js import { createRoot } from 'react-dom/client' import { RouterProvider } from 'react-router-dom' import router from '@/router' createRoot(document.getElementById('root')).render( <RouterProvider router={router}></RouterProvider> )
配置Zustand
模板代码
▼js复制代码//store\modules\counter.jsx export const createCounterStore = (set) => { return { count: 0, inc: () => { set((state) => { return { count: state.count + 1 } }) } } } //store\index.jsx import { create } from 'zustand' import { createCounterStore } from './modules/counter' const useStore = create((...a) => { //剩余参数(剩余参数运算符) return { ...createCounterStore(...a) //数组展开(展开运算符) } }) export default useStore //App.jsx import useStore from './store' // import { useState } from 'react' function App() { // const [count, setCount] = useState(0) const { count, inc } = useStore() return ( <> <div>this is App</div> <span>{count}</span> <button onClick={inc}>+</button> </> ) } export default App
配置axios
▼js复制代码//request.jsx import axios from 'axios' export const request = axios.create({ baseURL: 'http://127.0.0.1:8888/api/', timeout: 5000 }) request.interceptors.request.use( (config) => { //请求前逻辑,加请求头,判断登录状态等等 return config }, (error) => { return Promise.reject(error) } ) request.interceptors.response.use( (config) => { //响应后逻辑,拆一层axios的包装等等 return config }, (error) => { return Promise.reject(error) } ) //index.jsx export { request as http } from './request'
得失总结
上半年个人计算机二级优秀+蓝桥杯B组省二,下半年做了很多前端的小练习,上线了很多练习项目
近期最大的收获,期末不挂科✅
不过还是很多东西没做完
立了读书的目标,未达成,看久了视频教程就不太能读进去书了,尤其是理论书.
学习Linux使用未完成,半途而废(弄好的Java虚拟机近期也用不上),这个下学期肯定要继续的
五笔打字未完成,学会了理论,能打字,不过比起用微软双拼,五笔大概1-5秒一个字,慢太多了,就废弃了.
期末复习笔记本来要做的,不过不是很想看,就还是照期末冲刺留印象去了
英语零基础,期末考试完了就没再看过,也算废弃了.
对上线项目的管理不够标准,部分传码云,部分GitHub,部分free3v,还有部分干脆覆盖了,虽然都是课程里带着做的基础项目,不过还是挺可惜的.
还有就是本来想好好总结一下的,不过东西太多怕拖进度,就先点到为止了(关键的框架语法,表单规则和组件的一些总结都没做)
暂时想不起来更多了
学习打卡Day10
AI刷题一道√,今日冲总结,python停摆.
最后,提醒看到这里的各位大佬们——合理安排时间,享受健康生活。 向前~向前~向~前~~!
