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 ...
从零开始的mini-vue①--reactive篇
前言mini-Vue 是精简版本的 Vue3,包含了 vue3 源码中的核心内容,附加上 demo 的具体实现。本篇是 reactive 篇,是关于 Vue3 中响应式的篇章,包含了reactive,ref,computed的实现
项目构建项目使用 webpack 构建,demo 的代码放在index.js之中,将其打包成为mini-vue.js,之后index.html引入,控制台查看 demo 输出。
reactiveVue3 中的reactive用于处理对象数据,将引用类型的数据转化为响应式。其实它是由两个部分组成的,见例子。我们知道它由 reactive 和 effect 组成
123456const observed = reactive({ count: 0,});effect(() => { console.log("observed.count is:", observed.count);});
我们把这个 effect 叫做副作用函数,副作用函数的执行会影响其他变量或者函数的执行。这里它是作用是 ...
快速上手mongoose
前言Mongoose 是 MongoDB 的一个对象模型工具,是基于 node-mongodb-native 开发的 MongoDB nodejs 驱动,可以在异步的环境下执行。同时它也是针对 MongoDB 操作的一个对象模型库,封装了MongoDB 对文档的的一些增删改查等常用方法,让 NodeJS 操作 Mongodb 数据库变得更加灵活简单。记录使用MongoDB非关系型数据库时,使用Express+Mongoose的操作。
项目依赖初始化项目之后复制如下到package.json安装即可123456"dependencies": { "body-parser": "^1.20.0", "cors": "^2.8.5", "express": "^4.18.1", "mongoose": "^6.3.4"}
express模板由于只是演示操作,下列全部都写在了app.js ...