1,Promise构造函数是用来处理异步任务回调函数的一种方案,可代替callback函数
异步任务不会进入主线程而是由浏览器线程执行,执行完毕后会调用主线程的回调函数,promise就是用来处理这个回调函数
async(异步)关键词作用于函数体(主线程同步执行),用来标识函数内部有异步任务,await关键词用于async异步函数内部,用来阻塞线程等异步任务执行完毕再往下执行,await后的代码会打包成微任务,等回调函数返回后,进入主线程处理
状态:等待,成功,失败
2,构造函数
构造函数会自动创建一个空对象
工厂模式的情况下,构造函数相比普通函数可节省内存,普通函数多次调用就会创造一个新的方法副本
3,数组扁平化flat函数
arr.flat()
参数可以数字,或者不传(默认1),或者Infinity扁平化全部层级
4,异步组件:defineAsyncComponent
父组件加载会返回一个占位符,组件加载完成后替换占位符
优:加快初始化时间,按需加载,避免资源浪费
缺:动态导入会发起http请求,不利于浏览器爬取和索引
5,函数声明和函数表达式
函数声明会导致变量提升致作用域顶部,函数表达式是变量定义,重复定义会覆盖同名函数声明和函数表达式
6,vue2和vue3
响应式系统升级、写法更灵活,采用组合式api、diff算法优化Dom渲染性能提升,引入Tree Shaking打包体积更小、ts支持性更好
diff:在vue3数据改变后虚拟Dom生成真实Dom的过程中,对比新旧Vnode节点得出修改的最小单位
7,spa单页应用怎么加快加载速度
1,代码组件化,使用异步加载
2,资源预加载,懒加载,缓存重复使用的资源
3,静态资源使用CDN
4,不要重复请求api
5,循环dom使用有效的key值
6,较大的库使用外部扩展,如lodash
7,页面路由跳转有些页面能缓存就缓存
8,首次加载服务器端渲染快于客户端渲染
9,用户体验上用骨架屏之类的
8,组件传值
1,props和emit
2,provide和inject
3,状态管理(小型项目使用localstrorage或者全局变量)
4,事件总栈eventbus
5,uni.on和uni.emit
6,父传子,ref获取子组件的实例
7,作用域插槽
9生命周期函数
10,盒模型
每个元素都是一个矩形盒子,有外边距,内边距,边框,内容
标准盒模型:日常使用的,高宽为内容
怪异盒模型:高宽为内边距加边框加内容
• box-sizing: content-box; (默认值) - 使用标准盒模型。
• box-sizing: border-box; - 使用怪异盒模型。
11,响应式设计
一套代码适应不同分辨率
使用百分比,媒体查询,使用flex或者grid布局,unocss响应式前缀(sm:p-3,md:p-3)
媒体查询:
/* 超小设备 (手机, 小于 768px) /
/ 通常不需要 min-width 查询,因为这是默认的移动样式(Mobile First) */
/* 小型设备 (平板, 768px 及以上) */
@media (min-width: 768px) { ... }
/* 中型设备 (笔记本/小桌面, 992px 及以上) */
@media (min-width: 992px) { ... }
/* 大型设备 (大桌面, 1200px 及以上) */
@media (min-width: 1200px) { ... }
/* 也可以使用 max-width /
@media (max-width: 767px) { ... } / 仅对手机生效 */
12,CSS modules
样式合理,实现局部样式,类似vue的scoped
Css modules在编译时转换类名
Scoped在运行时修改类型,类名后添加属性标识
13,js原型链
每个对象都有原型链,如果访问这个对象的一个属性或者方法,这个对象本身没有就会去原型链上原型中逐个往上查找,直到找到或者原型链顶端Object.prototype,比如定义一个数组,使用data.toString(),因为原型链顶端有这个方法,所以可以执行成功
Es6的class 语法糖可以继承原型链
Class son extends father{}
14,js的事件循环Event Loop(无限循环,不会停止)
监听和调度任务,处理高并发的异步任务,保证单线程不会堵塞
先同步任务,微任务(promise回调函数,比如await接口返回后复赋值),再宏任务(settimeout),最后再检查有没有微任务需要执行
(微任务执行完毕,再执行一个宏任务,继续检查有没有微任务,全部任务完成后会进入休眠继续等待下一个进入的任务)
微任务:加急任务
宏任务:普通任务
15,在ts中生成dom
1,h函数生成虚拟节点VNode,render函数把虚拟节点生成真实dom
2,tsx < script setup lang="tsx">
16,vue-router
两种模式
hash:url中带#,通过hashchange实现路由切换,兼容性好
history:url正常模式,比较美观,通过pushstate和replacestate实现,需要服务器端支持,避免刷新出现404,利于seo优化(浏览器搜索引擎不解析url的#后内容)
17,导航守卫
路由跳转执行的钩子函数
router.beforeEach路由跳转前的前置守卫,用于验证登录,权限,页面是否存在等
router.afterEach路由跳转后的后置守卫
18,状态管理:管理全局共享数据和相应操作数据的方法
Pinia更轻量级,支持ts,写法使用组合式,默认支持模块化
19, vite打包体积过大
1,使用tree shaking
2,按需引入
3,开发环境需要的插件安装在开发配置中,不需要安装到生产配置
4,图片等静态资源使用cdn
5,配置高效的压缩算法
6,配置代码分割策略
20,Websocket
建立在http请求上的一个特殊请求
步骤:
1,建立连接
1.1,客户端握手
客户端发起一个new Websocket(url)请求,请求头带两个信息,标识是Websocket请求。
Upgrade: websocket // 将协议升级为Websocket
Connection: Upgrade // 此次连接需要转换协议
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 随机Base64 密钥,由浏览器生成
Sec-WebSocket-Version: 13 // 使用的 WebSocket 协议版本(13是现行标准)
1.2,服务器响应
服务器支持websocket则返回101响应,并同样返回这两个标识
Upgrade: websocket // 同意升级为Websocket
Connection: Upgrade // 确认转换协议
2,数据传输
握手成功后TCP保持打开,通过数据帧进行通信
数据帧头特别小,这是他能保证实时通信不延迟的原因
3,心跳机制
心跳机制用来检查websocket是否正常连接,服务器端向客户端发请求
前端实现
1,创建连接
// 使用 'ws://' 用于非加密连接(开发环境)
// 使用 'wss://' 用于加密连接(生产环境,等同于 HTTPS)
const socket = new WebSocket('wss://your-websocket-server.com/chat');
2,使用websocket方法获取服务器端数据或者向服务器端传递数据
3,完毕后在onUnmounted 中使用close方法清理连接
21,watch
监听多个属性
watch(
() =\> state.user.name, () =\> state.user.age\], (\[newName, newAge\], \[oldName, oldAge\]) =\> { console.log('name 或 age 变化了'); } ); 22,普通函数与箭头函数的区别 写法不一样,this指向不同,普通函数可作为构造函数,箭头函数不行 普通函数不return会返回undefined 22,typeof返回 类型 返回值 Undefined "undefined" Null "object" (历史遗留问题) Boolean "boolean" Number "number" BigInt "bigint" String "string" Symbol "symbol" Function "function" 其他对象 "object" 23,组件透传 24,实现v-model 一,使用update:modelValue \ 二,使用defineModel(vue3.3+) const modelValue = defineModel() // 带类型和默认值 const modelValue = defineModel('默认值') // 多个 v-model const firstName = defineModel('firstName', { default: '' }) const age = defineModel('age', { default: 0 }) 25,es6 26,nextTick 响应式数据更新后,会生成一个异步的微任务加入到队列,等待事件循环调度主线程执行这个微任务,nextTick就是一个特殊的promise异步任务,在等待数据更新的微任务执行完毕后再执行,所以他能保证获取到最新的Dom 27,闭包 闭包就是能够读取其他函数内部变量的函数,或者说是一个函数和其周围状态 原理: 函数在执行时,会创建一个作用域链。通过作用域链,内部函数可以访问外部函数的变量,即使外部函数已经执行完毕,只要内部函数还在被引用,外部函数的变量就不会被垃圾回收,从而被"封闭"在内部函数中。 28,作用域链 作用域:作用域就是变量和函数的可访问范围 作用域链:当在某个作用域内访问一个变量或函数时,JavaScript 引擎会遵循一个从当前作用域到外层作用域逐级查找的机制。这个查找路径就像一条链子,所以我们称之为作用域链。 29,深拷贝浅拷贝 "浅拷贝时,嵌套对象的内存地址指向同一个;深拷贝时,所有层次的内存地址都是不同的。" 浅拷贝,展开运算符{...obj},object.assign 浅拷贝只有嵌套对象的会指向同一个内存地址 深拷贝,cloneDeep 30,使用unocss实现媒体查询响应式样式 使用响应式前缀 31,组件开发 • 单一职责 - 每个组件只关注一个特定功能 • 可复用性 - 通过props和插槽提供灵活性 • 可维护性 - 清晰的接口和良好的文档 • 性能优化 - 合理使用响应式数据和生命周期 32,怎么实现一个vue3的路由 创建一个路由文件,实现路由配置,创建路由,然后挂载到main.ts中,页面使用router-link渲染路由链接,使用router- view显示路由页面 动态路由: 1,定义基础的路由文件,404,登录页等 2,从后端获取路由数据(main.ts或者apo.vue中预加载,路由守卫中按需加载) 3,转换路由格式{path,component,name,meta} 4,添加动态路由:router.addRoute(route) 5,路由守卫控制权限:router.beforeEach 6,渲染菜单:路由链接:router-link 路由视图:router-view 也可以使用component 标签实现,不需要3,4,6步 设置路由缓存: \ 插入的内容 \ 插入的内容 3,作用域插槽 ◦ 子组件定义: {{ user.name }} - {{ user.email }} 父组件使用: