我的笔记

12 阅读6分钟

大文件上传方案

  1. 计算文件hash
  2. 前端把文件hash传给后端,后端返回该文件是否存在,如果存在,直接秒传,不存在就进入分片上传流程
  3. 前端按固定大小切分文件,然后带上文件hash和分片序号上传,同时需要控制并发数
  4. 每次上传前,前端要查询已上传的分片,然后只上传剩余的分片
  5. 上传完成后,前端通知后端合并,后端按照分片序号拼接,返回文件地址

vite和webpack的区别

Vite 和 Webpack 最核心的区别:

  1. 启动和热更新速度不一样
  • Webpack 是全量打包,启动时要把所有依赖打包成 bundle,热更新也要重新打包相关模块,项目越大越慢。
  • Vite 在开发环境利用浏览器原生 ES Modules按需加载,不打包,所以启动非常快,热更新只更新修改的模块,也很块。
  1. 底层构建工具不一样
  • Webpack 自己一套完整打包流程。
  • Vite 开发时不打包,生产用 Rollup 打包。
  1. 定位不同
  • Webpack 生态成熟、配置复杂、适合大型复杂项目。
  • Vite 开箱即用、配置简单、现代框架(Vue/React)首选。

Vite 快在开发体验,Webpack 强在生态和兼容性。

性能优化

  • 网络上静态资源上CDN,使用缓存,合并请求
  • 加载上做图片懒加载、组件和路由懒加载
  • 渲染上减少回流重绘,动画用 transform
  • 运行时对高频事件防抖节流,长列表用虚拟列表

vue2和vue3响应式区别

1.vue2是通过数据劫持+发布订阅者模式去实现响应式的,是对data中的每个属性进行了递归遍历,把每个属性转换为setter和getter,不被使用的也会被转换。而vue3使用Proxy 直接拦截整个对象的操作。它采用了懒代理(Lazy Observation) 机制,只有当代码真正访问到嵌套对象时,这样渲染速度更快,内存占用更低。

ref reactive toRef的区别

  • ref:支持基本类型和对象,JS 中需通过 .value 访问。
  • reactive对象专用。仅支持对象/数组,直接访问属性
  • toRef:将 reactive 对象的单个属性转换为 ref

原型和原型链

每个函数都有prototype属性,这个prototype就是原型对象,每个对象都有__proto__属性,它指向的是创建它的构造函数的原型对象,而这个原型对象的__proto__属性指向的是它自己的原型对象,当查找对象中的某个属性或者方法时,如果查找不到就沿着__proto__向上查找,直到找到或者为null为止

vue组件通信方式

  • 父子组件通信: refpropref prop emit parentprovideinjectparent provide inject children v-model.sync 插槽
  • 隔代通信: provide inject
  • 任意组件:vuex pina
  • 属性透传:$attrs

vue3和vue2的区别

  • vue2都是选项式API,vue3都是组合式API,逻辑更加聚合
  • vue2只支持单根节点,vue3可以是多个根节点
  • vue3的setup替代了vue2的beforeCreated和created生命周期,其余周期需要在前面加on
  • vue2相比vue3引入了静态提升和patchFlag,渲染速度更快
  • vue2通过defineProperty实现的, 像对象增加属性、通过下标修改数组长度都是无法监听到的,而vue3通过proxy监听整个对象,弥补了这些缺陷

为什么要有key

key是列表中元素的唯一标识,Vue通过key来判断元素是否被修改、新增或删除。更新列表时,有key就能精准找到变化的元素,只更新它,不用重新渲染整个列表,这样性能更好。实际开发中建议用数据的唯一id做key,别用index,因为index会随列表排序、增删变化,可能导致key失效。

为什么会有nextTick

vue的的数据更新是异步的,数据更新之后不会立即更新DOM,而函数放在nextTick中执行,能确保在DOM更新之后执行函数

watch和watcheffect的区别

  • watch需要手动指定依赖,依赖改变才执行
  • watcheffect自动收集依赖,初始化的时候就会执行一次

事件循环

js是单线程的,为了避免任务阻塞,所以就有了事件循环机制。 js任务的执行顺序为:

  • 先执行完所有的同步任务
  • 再清空微任务,执行宏任务队列里第一个宏任务
  • 再清空微任务
  • 这样循环下去,直到执行结束

闭包

一个函数能够访问另一个函数内部变量的时候就会形成闭包 闭包的优点是可以私有化变量,避免全局污染 缺点:当外部函数执行完毕之后,内层函数仍保留着对外层函数作用域的引用,从而能继续访问外部变量,变量没有被回收,所以会占用内存导致内存泄漏。 解决办法:执行完闭包后,将外部函数赋值为Null

promise

promise是一种异步编程解决方案,用.then的链式调用解决了多层异步操作时的回调地狱问题 promise有三种状态:pending,resolved,rejected,,状态一旦发生改变就不会再变,状态的改变是通过resolve()和reject()方法来实现的。

async/await是promise的语法糖,写法更加简洁,逻辑更加清晰,易于调试,

数据类型

基本数据类型

undefined、null、string、boolean、number

复杂数据类型

对象、数组、函数

  • typeof判断数组|对象|null结果都是object.判断其余基本数据类型和function都能正确判断
  • instanceof能够正确判断引用数据类型。instanceof的运行机制是在数据的原型链中能否找到该类型的原型。

箭头函数和普通函数的区别

  1. 箭头函数写法更简洁
  2. 箭头函数没有自己的this,通过上下文确定自己的this
  3. 箭头函数没有自己的原型
  4. 箭头函数不能作为构造函数使用
  5. 函数体内没有arguments对象

改变this指向的方法

  1. 函数名.call(thisArg, arg1, arg2, ...)
  2. 函数名.apply(thisArg, [arg1, arg2, ...])
  3. 原函数.bind(thisArg, arg1, arg2, ...)

let cost var区别

作用域上,let和const是块级作用域,只在{}内有效,var是函数或全局作用域。变量提升方面,var会提升且初始化为undefined,let和const提升后在暂时性死区,不能提前用。赋值上,let可改,const声明基本类型不可改,对象属性能改。

CSS元素居中的方法

  1. flex布局
  2. 绝对定位+transform
  3. 子绝父相+上下左右0+margin:auto (固定宽高)