diff --git a/.gitignore b/.gitignore index b512c09..6a26af8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -node_modules \ No newline at end of file +node_modules +test.* +.vscode \ No newline at end of file diff --git a/aboutCSS.md b/aboutCSS.md index af046cc..24fa5d8 100644 --- a/aboutCSS.md +++ b/aboutCSS.md @@ -1,194 +1,227 @@ # 与 css 相关,多学习 css ## css inset -- inset : top | right| bottom | left -- 使用例: - ```css - .className { - inset: 4px 8px; /* 上下 | 左右 */ - inset: 5px 15px 10px; /* 上 | 左右 | 下 */ - inset: 2.4em 3em 3em 3em; /* 上 | 右 | 下 | 左 */ - } - ``` + +- 同时设置上下左右等多个属性值 +- inset : top | right| bottom | left +- 使用例: + ```css + .className { + inset: 4px 8px; /* 上下 | 左右 */ + inset: 5px 15px 10px; /* 上 | 左右 | 下 */ + inset: 2.4em 3em 3em 3em; /* 上 | 右 | 下 | 左 */ + } + ``` + ## css 过渡 transition -- 有transition-property、transition-duration、transition-timing-function 和 transition-delay这几个属性,不过一般使用时应该都是用transition合起来写。 -- 使用例: - ```css - .className { - /* property name | duration | timing function | delay */ - transition: margin-right 4s ease-in-out 1s; +- 有 transition-property、transition-duration、transition-timing-function 和 transition-delay 这几个属性,不过一般使用时应该都是用 transition 合起来写。 +- 使用例: - /* Apply to 2 properties */ - transition: margin-right 4s, color 1s; - } - ``` + ```css + .className { + /* property name | duration | timing function | delay */ + transition: margin-right 4s ease-in-out 1s; + + /* Apply to 2 properties */ + transition: margin-right 4s, color 1s; + } + ``` ## css 动画 滚动条驱动 -- animation-timeline -- 有时间再写 + +- animation-timeline +- 有时间再写 ## css 动画 -- 分为“定义”与“使用”两个阶段。 -- “定义”阶段的 keyword 为@keyframes,例: +- 分为“定义”与“使用”两个阶段。 +- “定义”阶段的 keyword 为@keyframes,例: - ```scss - // 每个时间点填对应时间点的style - @keyframes animationName { - 0% { - border-radius: 1px; - } - 50% { - border-radius: 12px; - } - 100% { - border-radius: 123px; - } - } - ``` + ```scss + // 每个时间点填对应时间点的style + @keyframes animationName { + 0% { + border-radius: 1px; + } + 50% { + border-radius: 12px; + } + 100% { + border-radius: 123px; + } + } + ``` -- “使用”阶段的 keyword 为 animation,使用 animation 绑定动画,例 - ```scss - div { - animation: animationName 5s; - } - ``` -- animation 有许多属性 +- “使用”阶段的 keyword 为 animation,使用 animation 绑定动画,例 + ```scss + div { + animation: animationName 5s; + } + ``` +- animation 有许多属性 - ```scss - div { - // 绑定的动画名 - animation-name: animationName; - // 动画执行总时长 - animation-duration: 5s; - // 速度曲线。默认是 "ease"。 - animation-timing-function: linear; - animation-delay: 2s; - // 播放次数,默认1 - animation-iteration-count: infinite; - // 是否在下一个周期逆向播放 - animation-direction: alternate; - // 是否正在播放() - animation-play-state: running; - // 简写 - animation: animationName 5s linear 2s infinite alternate; - // 多个动画之间使用逗号进行隔开 - animation: a1..., a2...; - } - ``` + ```scss + div { + // 绑定的动画名 + animation-name: animationName; + // 动画执行总时长 + animation-duration: 5s; + // 速度曲线。默认是 "ease"。 + animation-timing-function: linear; + animation-delay: 2s; + // 播放次数,默认1 + animation-iteration-count: infinite; + // 是否在下一个周期逆向播放 + animation-direction: alternate; + // 是否正在播放() + animation-play-state: running; + // 简写 + animation: animationName 5s linear 2s infinite alternate; + // 多个动画之间使用逗号进行隔开 + animation: a1..., a2...; + } + ``` ## before 与 after -- 伪元素,通过 content 来指定内容,before 就是在前面,after 就是在后面(哇好有道理呢) -- 用途一般是加个 icon 啥的,content 可以为 url(...) -- 不能应用在替换元素上,比如 `` -- 伪元素不支持嵌套,也就是说伪元素的父元素不可以为伪元素 - 使用例: +- 伪元素,通过 content 来指定内容,before 就是在前面,after 就是在后面(哇好有道理呢) +- 用途一般是加个 icon 啥的,content 可以为 url(...) +- 不能应用在替换元素上,比如 `` +- 伪元素不支持嵌套,也就是说伪元素的父元素不可以为伪元素 + 使用例: - ```css - a { - color: #0000ff; - text-decoration: none; - } + ```css + a { + color: #0000ff; + text-decoration: none; + } - a::before { - content: '🔗'; - } - ``` + a::before { + content: '🔗'; + } + ``` -- 使用 inherit 使子元素拥有与父元素相同的特定属性值 - 使用例: +- 使用 inherit 使子元素拥有与父元素相同的特定属性值 + 使用例: - ```css - div { - position: relative; - background: url('your-image-url.jpg'); - } + ```css + div { + position: relative; + background: url('your-image-url.jpg'); + } - div::before { - content: ''; - position: absolute; - top: 0; - left: 0; - background: inherit; - z-index: -1; - } - ``` + div::before { + content: ''; + position: absolute; + top: 0; + left: 0; + background: inherit; + z-index: -1; + } + ``` ## !important 相关 -- 不到万不得已不要用,是不好的写法 -- 如果你的 important 不够 important,那可以写 class 的时候多写点前缀,例: +- 不到万不得已不要用,是不好的写法 +- 如果你的 important 不够 important,那可以写 class 的时候多写点前缀,例: - ```scss - // 一般 - .ant-slider-rail { - background-color: rgb(141, 93, 56) !important; - } - // 优先级特别高 - .slider .ant-slider .ant-slider-rail { - background-color: rgb(141, 93, 56) !important; - } - ``` + ```scss + // 一般 + .ant-slider-rail { + background-color: rgb(141, 93, 56) !important; + } + // 优先级特别高 + .slider .ant-slider .ant-slider-rail { + background-color: rgb(141, 93, 56) !important; + } + ``` ## xx[a=xxx]的使用 -- 这玩意叫属性选择器 -- 案例: +- 这玩意叫属性选择器 +- 案例: + + ```css + a { + color: blue; + } + + /* 以 "#" 开头的页面内部链接 */ + a[href^='#'] { + background-color: gold; + } + + /* 包含 "example" 的链接 */ + a[href*='example'] { + background-color: silver; + } + + /* 包含 "insensitive" 的链接,不区分大小写 */ + a[href*='insensitive' i] { + color: cyan; + } + + /* 包含 "cAsE" 的链接,区分大小写 */ + a[href*='cAsE' s] { + color: pink; + } + + /* 以 ".org" 结尾的链接 */ + a[href$='.org'] { + color: red; + } + + /* 以 "https" 开始,".org" 结尾的链接 */ + a[href^='https'][href$='.org'] { + color: green; + } + ``` + + - 属性不一定要是 href 什么的,自己定也没关系。 + - 案例: + + ```css + /* 将所有包含 `lang` 属性的
元素的字重设为 bold */ + div[lang] { + font-weight: bold; + } + + /* 将所有语言为美式英语的
元素的文本颜色设为蓝色 */ + div[lang~='en-us'] { + color: blue; + } + + /* 将所有语言为葡萄牙语的
元素的文本颜色设为绿色 */ + div[lang='pt'] { + color: green; + } + ``` + +## grid ```css - a { - color: blue; + .container { + display: grid; + grid-template-columns: repeat(2, 100px 20px 80px); + /* repeat 配合auto-fill/auto-fit 配合minmax 实现自适应布局 */ + grid-template-columns: 1fr 1fr minmax(100px, 1fr); + grid-row-gap: 20px; + grid-column-gap: 20px; + /* 先行后列,尽可能填满 */ + grid-auto-flow: row dense; } - - /* 以 "#" 开头的页面内部链接 */ - a[href^='#'] { - background-color: gold; - } - - /* 包含 "example" 的链接 */ - a[href*='example'] { - background-color: silver; - } - - /* 包含 "insensitive" 的链接,不区分大小写 */ - a[href*='insensitive' i] { - color: cyan; - } - - /* 包含 "cAsE" 的链接,区分大小写 */ - a[href*='cAsE' s] { - color: pink; - } - - /* 以 ".org" 结尾的链接 */ - a[href$='.org'] { - color: red; - } - - /* 以 "https" 开始,".org" 结尾的链接 */ - a[href^='https'][href$='.org'] { - color: green; + .item-1 { + /* 边框所对应的网格线 */ + /* grid-column属性是grid-column-start和grid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。 */ + grid-column-start: 2; + grid-column-end: 4; + grid-column: 2/4; + grid-row: 1/2; } ``` +## point-event - - 属性不一定要是 href 什么的,自己定也没关系。 - - 案例: + 当为none时,所有点击事件无效 - ```css - /* 将所有包含 `lang` 属性的
元素的字重设为 bold */ - div[lang] { - font-weight: bold; - } - - /* 将所有语言为美式英语的
元素的文本颜色设为蓝色 */ - div[lang~='en-us'] { - color: blue; - } - - /* 将所有语言为葡萄牙语的
元素的文本颜色设为绿色 */ - div[lang='pt'] { - color: green; - } - ``` +## \ No newline at end of file diff --git a/aboutOthers.md b/aboutOthers.md index f7df997..653a66b 100644 --- a/aboutOthers.md +++ b/aboutOthers.md @@ -1,3 +1,101 @@ # 杂谈 记录一些碎碎念 + --- -npx用来临时使用一个库(如rollup) \ No newline at end of file + +npx 用来临时使用一个库(如 rollup) + +--- + +强缓存和协商缓存的 header 参数 +强缓存: +Expires:过期时间,如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求 +Cache-Control:当值设为 max-age=300 时,则代表在这个请求正确返回时间(浏览器也会记录下来)的 5 分钟内再次加载资源,就会命中强缓存。 +cache-control:除了该字段外,还有下面几个比较常用的设置值: +(1) max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒; +(2) s-maxage:和 max-age 是一样的,不过它只针对代理服务器缓存而言; +(3)public:指示响应可被任何缓存区缓存; +(4)private:只能针对个人用户,而不能被代理服务器缓存; +(5)no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到 请求,然后判断资源是否变更,是则返回新内容,否则返回 304,未变更。这个很容易让人产生误解,使人误 以为是响应不被缓存。实际上 Cache-Control: no-cache 是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。 +(6)no-store:禁止一切缓存(这个才是响应不被缓存的意思)。 + +--- + +mvvm: + +vm: 关注绑定器,将数据和视图绑定,自动更新,低耦合。model仅关注数据更新 + +--- + +垃圾回收相关: + +window.gc: 手动调用垃圾回收 + +现代主要使用标记清除法。 +进入执行环境的时候标记上。 +离开环境的时候直接回收。 + +常见的内存泄漏: +全局变量,解决方式: 全局变量 +定时器未清除:记得及时清除 +闭包: 解决方式: 及时设置为null +dom元素删除后未清除: 解决方式: 及时设置为null + +栈(Stack) +特点:栈是一种后进先出(LIFO, Last In First Out)的数据结构。 + +存储内容:用于存储简单的数据类型(如数字、字符串、布尔值)和函数调用上下文。 + +内存分配和释放:内存分配和释放非常快速,直接在栈顶操作。函数调用结束后,栈帧自动释放。 + +作用:主要用于管理函数调用和局部变量。 + +堆(Heap) +特点:堆是一种无序的数据结构,用于动态分配内存。 + +存储内容:用于存储复杂的数据类型(如对象、数组)。 + +内存分配和释放:内存分配比较灵活,但管理和回收内存需要垃圾回收机制(GC, Garbage Collection)来处理。 + +作用:用于存储需要动态分配的较大数据块和复杂数据结构。 + +--- + +babel相关: + +Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 + +--- + +es6几个主要的: +1. let, const +2. 箭头函数 +3. class +4. 模板字符串 +5. 解构 +6. 函数传参默认值&rest + +--- + +http响应头请求头 + +请求头: +content-type: 请求的数据的类型 +Authorization: 身份验证,如JWT这样的 +UA: 浏览器环境 + +响应头: +set-cookie +content-length +cache-control + +跨域cookie需要服务器进行设置 + + +--- + +SEO优化 + +1. 大量使用语义化标签 +2. 保证关键词覆盖率,title之类,配置meta信息 +3. 制定一个站点地图,放在“robot.txt”中 +4. 结构化数据 \ No newline at end of file diff --git a/aboutTS.md b/aboutTS.md index 8a02eef..dd78649 100644 --- a/aboutTS.md +++ b/aboutTS.md @@ -1,37 +1,192 @@ # 以下是关于 ts(以及任何关于 ts 的不限于语法,技巧之类的学习心得) ## any unknown void never -- any 表示任意类型。这导致不会对类型进行任何检查,用太多不太好就是了。 -- unknown 表示位置类型。看作any的安全版本。可以赋值为任何类型,但在使用之前必须进行类型检查或类型断言。 -- void 代表没有返回值。 -- never 代表永远不会有任何返回值,如死循环或抛出异常。 + +- any 表示任意类型。这导致不会对类型进行任何检查,用太多不太好就是了。 +- unknown 表示位置类型。看作 any 的安全版本。可以赋值为任何类型,但在使用之前必须进行类型检查或类型断言。 +- void 代表没有返回值。 +- never 代表永远不会有任何返回值,如死循环或抛出异常。 ## 接口 interface -- 基本可以认为是声明object类型用的东西 + +- 基本可以认为是声明 object 类型用的东西 ## 泛型 -- 实际上可以理解为是一种类型的变量 -- 如: - ```ts - function identity(arg: T): T { - return arg +- 实际上可以理解为是一种类型的变量 +- 如: + + ```ts + function identity(arg: T): T { + return arg + } + + // 使用泛型函数 + let result = identity('Hello') + console.log(result) // 输出: Hello + + let numberResult = identity(42) + console.log(numberResult) // 输出: 42 + + // 基本语法 + interface Pair { + first: T + second: U + } + + // 使用泛型接口 + let pair: Pair = { first: 'hello', second: 42 } + console.log(pair) // 输出: { first: 'hello', second: 42 } + ``` + +## 箭头函数与普通函数的区别 + +- 箭头函数没有 yield +- 无 prototype +- 没有 this 和 arguments + +## 使用 Object.freeze() + +- Object.freeze() 可以冻结一个对象,使其不能添加、删除或修改属性。 + + ```ts + const obj = { key: 'value' }; + Object.freeze(obj); + + obj.key = 'new value'; // 无效 + obj.newKey = 'new value'; // 无效 + delete obj.key; // 无效 + + console.log(obj); + ``` + +## 使用 Object.defineProperty()使对象某一 key 其不可变 + +- Object.defineProperty() 可以定义对象属性,并使其不可变。 + + ```ts + const obj = {}; + Object.defineProperty(obj, 'key', { + value: 'value', + writable: false, + configurable: false // 不可配置的 + }); + + obj.key = 'new value'; // 无效 + delete obj.key; // 无效 + + console.log(obj); // 输出: { key: 'value' } + ``` + +## Object.seal()。 + +- Object.seal() 可以让对象不能添加或删除属性,但允许修改现有属性的值。 + + ```ts + const obj = { key: 'value' }; + Object.seal(obj); + + obj.key = 'new value'; // 有效 + obj.newKey = 'new value'; // 无效 + delete obj.key; // 无效 + + console.log(obj); + ``` + +## 判断是否为数组 + +- Array.isArray() +- instanceof Array +- obj.**proto** === [].**proto** + +## 是否为 NaN + +- Number.isNaN() + +## obj 可迭代 + +- 实现了迭代器协议(拥有 Symbol.iterator 方法)实现了迭代器协议(拥有 Symbol.iterator 方法) + + ```ts + const iterable = { + *[Symbol.iterator]() { + yield 1; + yield 2; + yield 3; } + } + ``` - // 使用泛型函数 - let result = identity('Hello') - console.log(result) // 输出: Hello +## promise新的 - let numberResult = identity(42) - console.log(numberResult) // 输出: 42 +- Promise.race(iterable) 接受一个可迭代对象,返回第一个解决或拒绝的 Promise 的结果。 +- Promise.allSettled(iterable) 接受一个可迭代对象,返回一个 Promise,所有 Promise 无论解决或拒绝都会返回结果。 +- Promise.any(iterable) 接受一个可迭代对象,返回第一个成功解决的 Promise 的结果。如果所有 Promise 都被拒绝,则返回一个拒绝的 Promise。 - // 基本语法 - interface Pair { - first: T - second: U - } +## deepReadonly + +```ts +type DeepReadonly = { + readonly [P in keyof T]: T[P] extends object ? DeepReadonly : T[P] +} + +``` + +## callable的对象 + +```ts +const callableObject = { + [Symbol('callable')](...args) { + console.log('Object called with args:', ...args); + // 执行一些操作并返回结果 + return args.reduce((sum, val) => sum + val, 0); + } +} +``` + +## 异步迭代 + +```ts +const asyncIterable = { + async *[Symbol.asyncIterator]() { + yield await new Promise(resolve => setTimeout(() => resolve(1), 1000)); + yield await new Promise(resolve => setTimeout(() => resolve(2), 1000)); + yield await new Promise(resolve => setTimeout(() => resolve(3), 1000)); + } +}; + +(async function() { + for await (const value of asyncIterable) { + console.log(value); // 输出: 1, 2, 3,每个值之间间隔1秒 + } +}) +``` + + +--- + +二进制/文件处理 + +blob: 一种类文件对象,只能使用fileReader进行异步读取,读取为arrayBuffer + +arraybuffer: 一种通用的二进制数据缓冲区,需要通过视图(如uint8array)进行修改 + +--- + +关于闭包,有逻辑的回答: + +闭包(closure)指有权访问另一个函数作用域中变量的函数。 ----- JavaScript 高级程序设计 +闭包有什么用? + +延伸变量作用域范围,读取函数内部的变量 +让这些变量的值始终保持在内存中 + +简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。 + +--- + +weakMap + +key必须为一个obj +可以用于给一个obj附加一些生命周期相同的数据内容(如缓存) - // 使用泛型接口 - let pair: Pair = { first: 'hello', second: 42 } - console.log(pair) // 输出: { first: 'hello', second: 42 } - ``` diff --git a/aboutVUE3.md b/aboutVUE3.md index dbc1915..f0366f0 100644 --- a/aboutVUE3.md +++ b/aboutVUE3.md @@ -4,7 +4,8 @@ --- # 子子组件之间的通信可以通过事件总线(eventBus)实现 --- -# doucument.createElement出来的东西不及时销毁就会一直游离在外面不被释放,积累下来很不好。 + +# doucument.createElement出来的东西不及时销毁就会一直游离在外面不被释放,积累下来很不好。(似乎是错误的) --- @@ -12,7 +13,7 @@ 组件设计可以分成业务组件,展示组件,展示组件只负责以对应的形式展示对应的数据,对于业务的处理(如增删查改),则需要通过emit或其他方法交给业务组件处理 --- -# 路由返回拦截hook +# 路由返回拦截hook(路由守卫) * 当点击返回键(浏览器或者是页面上的路由返回功能)时触发,形式如下: ```ts import { onBeforeRouteLeave } from 'vue-router' @@ -27,7 +28,7 @@ onBeforeRouteLeave((to, from, next) => { next(true) }) ``` -* 当next(false时,取消路由原有的返回功能) +* 当next===false时,取消路由原有的返回功能 --- ## 具名作用域插槽 * 具名作用域插槽的工作方式也是类似的,插槽 props 可以作为 v-slot 指令的值被访问到 @@ -82,4 +83,56 @@ example:
+``` + +# 路由相关: + +* 路由守卫 + +- - beforeEach 全局前置守卫 + + 作用: + 主要用于在路由跳转前进行权限验证、页面加载状态的设置等操作。例如,判断用户是否已经登录,如果没有登录且要访问需要登录才能访问的页面,就可以将用户重定向到登录页面。 + 它可以对每一次路由跳转进行全局拦截,是控制路由访问权限的重要手段。 + +- - afterEach全局后置守卫 + + 作用: + 它在路由跳转完成后被调用,主要用于记录页面访问历史、修改页面标题或者进行一些不需要阻塞路由跳转的操作。 + 例如,根据不同的路由来更新文档的标题,或者发送页面访问统计数据到服务器。 + +- - 全局解析守卫(beforeResolve)的触发时机 + + 全局解析守卫beforeResolve在路由导航被触发后,在所有组件内守卫和异步路由组件被解析之前调用。它是在beforeEach之后,但是在组件实例创建和beforeRouteEnter等组件内守卫之前执行。这意味着它处于路由导航过程的一个中间阶段,此时路由已经被匹配,但组件还没有完全解析和进入。 + 主要作用 + 数据预获取: + 可以用于获取组件渲染所需的数据。与beforeEach不同的是,beforeResolve更专注于确保在组件真正开始渲染之前,所有必要的数据都已经获取并准备好。例如,对于一个包含多个嵌套组件的复杂页面,其中每个组件都需要从服务器获取数据,beforeResolve可以协调这些数据获取操作,确保所有数据都准备好后再进行组件渲染。 + 处理异步操作的集中点: + 它为处理整个路由导航过程中的异步操作提供了一个集中的位置。在大型应用中,可能会有多个异步操作需要在路由跳转时完成,如加载第三方脚本、初始化插件等。beforeResolve可以用于确保这些异步操作都顺利完成后再继续路由解析过程。 + +- - 组件路由守卫 +```vue + ``` \ No newline at end of file diff --git a/杂项/ResizeObserverComponent.md b/杂项/ResizeObserverComponent.md new file mode 100644 index 0000000..ee5aae9 --- /dev/null +++ b/杂项/ResizeObserverComponent.md @@ -0,0 +1,86 @@ +```ts +import { + defineComponent, + watch, + onMounted, + onBeforeUnmount, + h, + getCurrentInstance, + type PropType, +} from 'vue-demi' +import ResizeObserver from './ResizeObserver' +import type { IOptions } from './types' + + +// const component = { +// name: 'Home', +// props:{ +// data: String, +// }, +// setup(props, context){ +// // props.data +// // context.attrs context.slots context.emit +// } +// } + +export default defineComponent({ + name: 'ResizeObserverComponent', + props: { + target: [String, Object] as PropType, + disabled: Boolean as PropType, + immediate: Boolean as PropType, + delay: { + type: Number as PropType, + default: 150 + } + }, + setup(props, { slots }) { + let ro: ResizeObserver | null = null + watch(() => props.disabled, (val) => { + if (val) { + ro?.disconnect() + } else { + ro?.observe() + } + }) + onMounted(() => { + // const { target, disabled, limiter, wait } = toRefs(props) + // 拿到当前组件的实例(注意已挂载) + const vm = getCurrentInstance()?.proxy + + // 先用$el + let $el: HTMLElement = vm?.$el as HTMLElement + + if (props.target) { + if (typeof props.target === 'string') { + $el = document.querySelector(props.target) as HTMLElement + } else if (props.target instanceof HTMLElement) { + $el = props.target + } + } + const options: IOptions = { + delay: props.delay, + immediate: props.immediate, + resize: (data, elem) => { + vm?.$emit('resize', data, elem) + } + } + ro = new ResizeObserver($el, options) + }) + // 销毁 ResizeObserver实例 + onBeforeUnmount(() => { + if (ro) { + ro.destroy() + } + }) + + // 如果有单个子元素则直接渲染子元素 + const defaultContent = slots.default?.() + return () => ( + (defaultContent && defaultContent.length === 1) + ? defaultContent[0] + : h('div', defaultContent) + ) + } +}) +``` \ No newline at end of file diff --git a/杂项/mvvm.md b/杂项/mvvm.md new file mode 100644 index 0000000..e69de29