TypeScript_Challenges
前言开始提前批直通车啦~~ 本篇带来 ts 超集的各种挑战加个人解说。源码地址:传送门
Hello World
1type HelloWorld = string;
Pick
code
12345type MyPick<T, K> = {};type MyPick<T, K extends keyof T> = { [P in K]: T[P];};
解释:pick 就是获取第一个参数的类型的其中几个,写法是Pick<target,'属性1'|'属性2'>,所以要实现他,就是说第二个属性要在 T 中,extends keyof 保证 K 的所有的类型在 T 中,in 保证 P 所有的类型在 K 中。
那么这里会有一个疑问。in 和 keyof 的区别
首先 keyof 是取 interface 的联合类型,
123456interface UserInfo { userName: "jojo"; psw: "123"; ...
Vue3+Canvas实现动态登陆背景页面
前言好久好久没写博客了,人一旦停止记录,就会感觉学习没有积累。虽然相应的有更多时间去coding,不过记录一下才更不容易忘记。
展示效果
起因其实对particle熟悉的话,就知道这个和他基本上是一样的效果,为什么不直接用particle呢?首先是因为nuxt3开发不知道怎么使用这个插件,只好网上cv一个然后改成对应的vue代码,不过改代码也是一件慢慢进步的事情。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 ...
HTML基础面
前言网站开发中,如何实现图片的懒加载懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片
故问题拆分成两个:
如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)
如何控制图片的加载
方案一: 位置计算 + 滚动事件 (Scroll) + DataSet API如何判断图片出现在了当前视口clientTop,offsetTop,clientHeight 以及 scrollTop 各种关于图片的高度作比对
这些高度都代表了什么意思?
这我以前有可能是知道的,那时候我比较单纯,喜欢死磕。我现在想通了,背不过的东西就不要背了
所以它有一个问题:复杂琐碎不好理解!
所以只知道静态的还不够,还要知道动态的。
如何动态?监听 window.scroll 事件
如何控制图片的加载?
1<img data-src="jojo.jpg" />
设置个临时的 data 属性 data-src,控制加载的时候使用 src 替代。利用 DataSet API 实现
1img.src = img.datset.src;
方案二: getBoundingC ...
从零开始的mini-vue⑧--parse篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是模板编译 Intro 篇,是关于 Vue3 中模板编译的简单介绍。
编译的目的之前我们编译都是以手写渲染函数的形式进行的,因此进行模板编译的目的就是将模板代码编译成渲染函数
来看一下 vue 是怎么把模板编译成渲染函数的
这里的_createElementBlock就相当于 h 函数,_toDisplayString就是为了转换插值符号 msg 的结果
这里值得一提的是 vue 能支持 jsx 的原理,因为 jsx 的最终产物也是一段渲染函数。
编译的步骤
parse原始的模板代码就是一段字符串,通过解析 parse 转为原始的 AST 抽象语法树
transformAST 经过 transform 生成一个 codegenNode。codegenNode 是 AST 到生成渲染函数代码的中间步骤,它由原始的 AST 语义而得来。比如对于原始的 AST 来说:
12<div v-if="ok"></div><div ...
从零开始的mini-vue⑦--scheduler篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是 scheduler 篇,是关于 Vue3 中调度机制的深入讨论。
为什么需要 scheduler在我们上节组件的实践中,我们跑了一个这样的例子
123456789101112131415161718192021222324252627282930import { render, h } from "./runtime";import { ref } from "./reactiveDemo/ref";const Comp = { setup() { const count = ref(0); const add = () => { count.value++; console.log(count.value); }; return { count, add, & ...
从零开始的mini-vue⑥--component篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是 Component 篇,是关于 Vue3 中组件的深入讨论。
组件是什么从开发者的视角来看,组件分为状态组件和函数组件,vue 其实也有函数式组件,但它和状态组件,从实现上来讲几乎没有多大区别,因此我们只考虑状态组件,以下所讲的组件都是状态组件
React 的组件示例
12345678910111213141516171819class Counter extends React.Component { state = { count: 0, }; add = () => { this.setState({ count: this.state.count + 1, }); }; render() { const { count } = this.state; return ( <> ...
从零开始的mini-vue⑤--最长上升子序列篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是最长上升子序列 篇,是关于 Vue3 中 LIS 的深入讨论。
LISLongest Increasing Subsequence 最长上升子序列。是指一个序列中最长的单调递增的子序列。
我们可以拿 leetcode 的题作为例子来编写:最长递增子序列
dp O(n²)例子:nums=[10,9,2,5,3,7,101,18]dp 的思路如下:
初始化 dp 为 1 dp=[1,1,1,1,1,1,1,1],然后循环比对前面的,只要它大于了前面的数就把下标置为前面的数的最大长度+1,当然这个过程还要比较和自身的大小,如果自身更大取自身.最后返回最大值
过程
1210 9 2 5 3 7 101 18 1 1 1 2 2 3 4 4
代码
12345678910111213141516var lengthOfLIS = function (nums) { // 最小是1 let dp = new Array(nums.length).fill(1) ...
从零开始的mini-vue③--patch篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是patch 篇,是关于 Vue3 中 patch 的基本理解和实践。
patch的介绍
patch 是对比新旧节点的算法,当新节点不存在的时候,执行卸载操作,当新节点存在的时候,进行对比
卸载操作需要判断对应节点的类型,如果是组件执行组件的卸载,如果是 Fragment 执行 Fragment 的卸载,最后到 Text 和 Element 执行 removeChild
patch 操作需要判断新旧节点的类型是否相同,不同的话就要卸载旧的节点将原有的节点树完全卸载掉。
然后再判断新节点新节点是否是组件,如果是则进行 processComponent;
新节点如果是 Text 类型,执行 processText。之后再来判断旧节点是否存在,如果存在说明之前已经创建过旧的文本内容了,直接复用这个文本节点,更新他的 textContent,如果不存在旧节点,直接使用 mountTextNode 挂载文本节点
新节点如果是 Fragment 类型,就执行 processFra ...
从零开始的mini-vue④--核心diff篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是核心 diff 篇,是关于 Vue3 中 patch 的深入讨论。
patchArrayChildren 的问题在上一节我们实现了patchArrayChildren,但是我们这个实现是比较简单粗暴的,直接对数组一对一进行的 diff 操作。
实际上它还是存在一些问题的,看下面的例子
c1: a b cc2: x a b c
我们在新孩子头部插入了一个节点,很明显我们只要在 a 前面插入一个 x 即可。但是按照我们现在的做法,它需要每个都变化一次。
所以有没有办法解决这个问题?有的,就是要引入一个 key 去告诉框架什么节点是应该去复用的,从而减小操作虚拟 DOM 的次数
而我们前面实现的 patchArrayChildren 其实就是 patchUnkeyedChildren
这里先偷个懒 只要第一个元素有 key 就当作有 key
12345678if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) { ...
从零开始的mini-vue②--vnode篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是虚拟 DOM 篇,是关于 Vue3 中响应式的篇章,包含了vnode,render的实现
vnode本节中我们将会实现这样的例子(注意 html 中使用 defer 挂载 js,以及使用样式)
1234567891011121314151617181920212223242526272829303132333435363738import { render, h, Text } from "./runtime";// 利用h生成vnodeconst vnode = h( "div", { class: "a b", style: { border: "1px solid", fontSize: "14px", }, onClick: () => console.lo ...