vue相关
vue2与vue3的区别
-
- 响应式原理差异
- Vue2:基于
Object.defineProperty实现,通过劫持对象的getter/setter追踪依赖。 - 缺陷:无法监听对象新增属性、删除属性,以及数组索引 / 长度变化(需用
Vue.set等特殊 API)。 - Vue3:基于
Proxy实现,直接代理整个对象而非属性。 - 优势:天然支持监听对象新增 / 删除属性、数组索引 / 长度变化,无需额外 API;
-
- 组件写法差异
- Vue2:Options API(选项式 API),将代码按
data、methods、computed等选项分类 - Vue3:Composition API(组合式 API),允许按逻辑功能组织代码,更适合复杂组件
-
- 生命周期钩子
- Vue2:生命周期选项(如
created、mounted)直接定义在组件选项中。 - Vue3:生命周期钩子需从
vue导入,在setup中调用(名称有变化,如mounted→onMounted)。
-
- 虚拟 DOM 与编译优化:
- Vue2:虚拟 DOM 全量对比,编译时无优化,运行时不管节点是否变化都需遍历对比,性能有瓶颈。
- Vue3:编译阶段优化:通过「静态标记」标记不会变化的节点(如纯文本、静态属性),运行时跳过这些节点的对比; 引入「补丁标志」:精确标记节点中变化的部分(如文本、class、样式),只更新需要变化的内容,提升渲染性能。
-
- 性能与体积优化
- 体积更小:Vue3 移除了部分不常用 API(如
filter),并采用 Tree-Shaking 技术,只打包使用到的 API,相比 Vue2 体积减少约 40%; - 启动速度更快:编译优化以及虚拟DOM优化
- 更好的TS支持,Vue2 对 TypeScript 支持较弱(需通过
vue-class-component等库扩展)
双向绑定与响应式
-
有关双向绑定 想一想为什么数据变化能更新视图,视图变化能更新数据?
- 双向绑定的实现基于 Vue 的两个核心机制:
- 数据响应式:通过
Object.defineProperty拦截属性的getter与setter(Vue2)或Proxy(Vue3)拦截数据的读取和修改,实现数据变化的监听。 - DOM 监听:通过事件监听(如
input、change)捕获用户对视图的操作,同步更新数据,,监听虚拟DOM变化
- 数据响应式:通过
- 核心思路都是 “数据驱动视图 + 视图监听更新数据”,联想v- model实现原理
- 双向绑定原理:
- 数据劫持:通过
Object.defineProperty监听数据(data)的get和set操作; - 依赖收集:在数据被访问时(
get),收集依赖该数据的「Watcher」; - 发布更新:当数据被修改时(
set),通知所有依赖的「Watcher」更新视图; - 视图反馈:通过事件监听(如
input事件)将用户输入同步回数据,形成双向绑定。
- 数据劫持:通过
- 双向绑定的实现基于 Vue 的两个核心机制:
-
为什么要两种有定义响应式变量的方式
ref和reactive的分工本质是适配 JavaScript 基础类型与引用类型的差异- 用
ref处理基础类型,通过.value访问,ref也可以处理引用类型(但会自动转为reactive代理)
const user = ref({ name: 'Tom' }) // 等价于 user.value = reactive({ name: 'Tom' })- 用
reactive处理对象 / 数组(复杂结构),直接访问属性。 - ref支持重新赋值保持响应式,reactive对象赋值后会丢失响应式
-
ref 为什么js使用变量时,需要.value
- 这涉及到proxy ,基础类型数据(比如number、string等)等无法被proxy直接代理(Proxy 需要代理对象),ref会把它们包装成对象,这个包装对象可以被 Vue 的响应式系统(Proxy)拦截,从而实现对
value的读取(get)和修改(set)的监听。
- 这涉及到proxy ,基础类型数据(比如number、string等)等无法被proxy直接代理(Proxy 需要代理对象),ref会把它们包装成对象,这个包装对象可以被 Vue 的响应式系统(Proxy)拦截,从而实现对
-
reactive局限性----- reactive()返回一个proxy对象,官方建议使用
ref()作为声明响应式状态的主要 API- 它只能用于对象类型 (对象、数组和如
Map、Set这样的集合类型)。它不能持有如string、number或boolean这样的原始类型; - 不能替换对象,替换的话与第一个引用的响应性连接将丢失;
- 解构变量丢失响应性:响应式对象的属性解构为本地变量时,或者将该属性传递给函数时,将丢失响应性连接
- reactive响应式丢失解决----避免直接赋值+不解构(使用toRefs()转成ref变量);通过修改属性到达效果;可以使用Object.assign(xx,{...})实现保持响应式;
- 它只能用于对象类型 (对象、数组和如
-
自动解包场景
- 模板「浅层」自动解包,如果
ref嵌套在普通对象中,不会自动解包(需手动.value)- 也可以把它解构出来作为顶级属性,比如const object = { id: ref(1) } 中的id--》const { id } = object就可以在模版中使用{{id}}
- 当
ref被嵌套在reactive对象中时,访问该属性会自动解包(无需.value)
- 模板「浅层」自动解包,如果
一些重要的语法
-
计算属性computed与属性监听
- 计算属性值会基于其响应式依赖被缓存;
- 计算属性的 getter 应只做计算而没有任何其他的副作用,比如不要改变其他状态、在 getter 中做异步请求或者更改 DOM
- watch:监听reactive会自动开启深度监听(ref需手动开启),vue3新增了
watchEffect会自动追踪回调中使用的响应式数据(隐式监听);侦听响应式对象的属性值需要()=>obj.xxx
-
生命周期
- 生命周期名字加on,去掉了(before)created(==setup执行时机),destroy变成unmount
-
组件props(输入) event(输出)
- 单向数据流:props 是只读的,组件内部不能直接修改,需通过事件通知父组件更新
-
hooks 逻辑复用,mixin会容易冲突、阅读起来困难
-
v-if与v-for
- 当它们同时存在于一个节点上时,
v-if比v-for的优先级更高,但它无法访问v-for中定义的变量,可以嵌套一层template解决 - v-for的key的作用:帮助 Vue 识别列表中的每个元素的唯一性,从而更高效地更新 DOM
- DOM更新:
- 数据变化:响应式数据被修改,触发 setter 或 Proxy 拦截。
- 通知依赖:依赖管理器(
Dep)通知相关 watcher 执行更新。 - 生成新虚拟 DOM:组件重新渲染,生成新的虚拟 DOM 树。
- Diff 对比:对比新旧虚拟 DOM,计算最小更新范围。
- 批量更新 DOM:根据 Diff 结果生成补丁,批量应用到真实 DOM。
- 当它们同时存在于一个节点上时,
-
nextTick 当数据变化时,Vue不会立即更新 DOM,而是将所有更新请求缓存,批量进行更新,nextTick是在DOM 更新完成后(就好像 其实是虚拟DOM计算的结果)执行操作 (这其实跟浏览器的内部处理机制有关,js线程执行会阻塞浏览器渲染进程==DOM更新,Vue框架在其中的作用是它有做一个收集+监听所有数据更新的操作,VUE内部有检测的虚拟DOM的变化,nextTick回调执行在一轮事件循环的末端,所以就算此时浏览器的真实DOM还没有更新,nexttick()里面通过新虚拟DOM可以获取到DOM更新后的结果)
pinia
通过 defineStore 定义一个 Store,第一个参数是唯一的 id(用于区分不同 Store),第二个参数是配置对象(包含 state、actions、getters);
解构store可避免响应式丢失直接解构 Store 会丢失响应式,需使用 storeToRefs 辅助函数;
优势:
- 无需
mutation,直接在actions中修改状态,更简单 - 完美支持 TypeScript 和组合式 API
- 轻量且灵活
自定义指令
生命周期:
created:元素初始化时(还未插入 DOM)。mounted:元素插入 DOM 后(最常用,适合初始化操作)。updated:元素更新时(组件更新后)。unmounted:元素从 DOM 中移除时(适合清理操作
路由
vue封装组件的要点
- 复用性(适配多种场景):合理设计 Props(输入,明确类型和默认值)与 $emit(输出);多传入少写死;
- 可维护性(好懂、好改)+易用性:文档与易用性(清晰注释:组件功能、Props 含义、Events 触发时机需注释)
- 扩展性:插槽设计(默认插槽、具名插槽、作用域插槽=父组件定义的插槽中可以访问子组件的数据);支持自定义类名与样式:提供
class和styleProps,允许用户覆盖默认样式 - 其他:样式隔离(局部样式,深度选择器:需要修改子组件样式时,用
::v-deep(Vue2)或:deep()(Vue3)穿透scoped)
三、vite/webpack 特点以及原理
webpack
以前的webpack只认识js,通过loader将其他语言转化,plugin是插件,可以扩展webpack的功能
- loader:babel-loader 把ES6转成ES5 css-loader:加载css sass-loader:转化成CSS、eslint-loader, style-loader:css注入js中 vue-loader html-loader
- plugin:
html-webpack-plugin:简化创建html文件clean-webpack-plugin目录清理HotModulePlugin热更新 - webpack构建流程 :初始化配置,加载plugin,实例化compiler,开始编译从entry出发,分析所有模块依赖(如
import/require),调用loader去加载模块(loader转换非JS资源(如 CSS 转 JS 模块)),将模块转化成chunk文件,最后输出到outputdir; - 缺陷:全量打包 无论开发环境(dev)还是生产环境(build),都需要将所有代码(JS、CSS、图片等)递归打包成一个个 “bundle 文件”(如
main.js);开发环境下,项目越大,打包时间越长,启动和热更新速度越慢。
vite
启动速度快 热更新速度快 无需手动配置loader,开发环境和生产环境采用不同策略,优化开发体验:
- 开发环境(dev) :不打包,直接利用浏览器原生支持的 ESM(
<script type="module">)加载模块。Vite 仅作为 “代理服务器”,接收浏览器请求时,实时转换非 ESM 资源(如将 Vue/React 单文件组件转 ESM、处理 TS),无需等待全量打包,启动和热更新极快。 - 生产环境(build) :基于 Rollup 打包(Rollup 比 Webpack 打包体积更小、Tree-Shaking 更彻底),输出优化后的 bundle 文件,兼顾性能和兼容性。
- 缺陷:Vite:默认不支持 IE 浏览器(因依赖 ESM,IE 不支持),需额外配置插件
JS
原型
- new一个对象
事件循环
四个线程:js线程、处理异步http请求线程+处理定时器线程(执行完毕后把回调函数推入队列中)、管理队列的线程
闭包
proxy
promise
浏览器相关
浏览器引擎/工作原理-------
把浏览器比做一个普通应用,要让它在windows系统运行,你要实现它的主要功能:
- 输入一个URL可以获取服务器资源(html+CSS+js),解析这些资源,展示页面
- 页面支持
- 支持打开多个标签页,页面刷新 收藏等等
兼容性问题
- 为什么会有兼容性问题?
- W3C推出的新特性,各个浏览器版本更新会逐步去支持新特性,但它们的旧版本可能不兼容;
- 不同的的浏览器使用的内核不一样,对标准的实现存在差异,
Chrome/Safari 用 WebKit/Blink,Firefox 用 Gecko,Edge 基于 Blink
- 存在哪些兼容性问题?
- 比如:
new Date('2023-13-01')有些浏览器会报错,Safari、IE、Firefox也无法正确解析YYYY-MM-DD格式的日期字符串,而Chrome可以正常处理 - 一些新出的ES6+语法,旧版本浏览器可能不支持
- CSS3(animation、transition、圆角、渐变、阴影等等)、HTML5
- 比如:
- 如何解决兼容性问题?
- 可以在
package.json中添加browserslist字段,配置目标浏览器 - 构建工具中通过babel-loader 把ES6转成ES5
- 用 Autoprefixer 自动添加 CSS 前缀(如
-webkit-) - API polyfill,比如让工具(如
core-js)只引入必要的polyfill,减少代码体积
- 可以在
移动端
NodeJS
TS
如何自己搭建脚手架
算法
设计模式
观察者模式:一对多,被观察者(数据),观察者
AI工具
- cursor
- 通用rules编写(比如技术栈、代码规范、git操作、API请求等等)
- mcp 让cursor帮你执行操作
对于简历的解读
微信小程序如何对移动端设备进行优化?
- 系统适配:不同操作系统的差异性处理:使用uniapp的条件编译,比如针对IOS与安卓系统的导航栏高度、弹窗的层级问题处理;
- 屏幕适配:使用rpx单位,结合flex
- 微信版本适配:针对低版本微信客户端,用 wx.canIUse 检测 API 兼容性,不支持的做降级处理
- 手机品牌适配:比如华为的刘海屏处理,通过uni获取设备参数,去判断做特殊处理
5.性能优化:
- 优化请求:使用本地存储减少请求、压缩资源
- 优化首屏加载:分包(控制小程序体积)、图片懒加载(只加载 “用户当前可见区域” 内的图片)、代码Tree Shaking
- 优化渲染性能:长列表使用虚拟列表、数据批量更新等等
微前端qiankun
- 主应用(host) :负责整合所有微应用(注册),提供公共的导航、权限、全局状态等基础能力。
- 微应用(app) :被拆分出来的独立子应用(如首页、商品页、用户中心等),可单独开发、测试、部署。
- 生命周期:微应用有
bootstrap(初始化)、mount(挂载)、unmount(卸载)等生命周期钩子,可接收从主应用传过来的参数。