2025

23 阅读11分钟

vue相关

vue2与vue3的区别

    1. 响应式原理差异
    • Vue2:基于 Object.defineProperty 实现,通过劫持对象的 getter/setter 追踪依赖。
    • 缺陷:无法监听对象新增属性、删除属性,以及数组索引 / 长度变化(需用 Vue.set 等特殊 API)。
    • Vue3:基于 Proxy 实现,直接代理整个对象而非属性。
    • 优势:天然支持监听对象新增 / 删除属性、数组索引 / 长度变化,无需额外 API;
    1. 组件写法差异
    • Vue2:Options API(选项式 API),将代码按 datamethodscomputed 等选项分类
    • Vue3:Composition API(组合式 API),允许按逻辑功能组织代码,更适合复杂组件
    1. 生命周期钩子
    • Vue2:生命周期选项(如 createdmounted)直接定义在组件选项中。
    • Vue3:生命周期钩子需从 vue 导入,在 setup 中调用(名称有变化,如 mounted → onMounted)。
    1. 虚拟 DOM 与编译优化:
    • Vue2:虚拟 DOM 全量对比,编译时无优化,运行时不管节点是否变化都需遍历对比,性能有瓶颈。
    • Vue3:编译阶段优化:通过「静态标记」标记不会变化的节点(如纯文本、静态属性),运行时跳过这些节点的对比; 引入「补丁标志」:精确标记节点中变化的部分(如文本、class、样式),只更新需要变化的内容,提升渲染性能。
    1. 性能与体积优化
    • 体积更小:Vue3 移除了部分不常用 API(如 filter),并采用 Tree-Shaking 技术,只打包使用到的 API,相比 Vue2 体积减少约 40%;
    • 启动速度更快:编译优化以及虚拟DOM优化
    • 更好的TS支持,Vue2 对 TypeScript 支持较弱(需通过 vue-class-component 等库扩展)

双向绑定与响应式

  1. 有关双向绑定 想一想为什么数据变化能更新视图,视图变化能更新数据?

    • 双向绑定的实现基于 Vue 的两个核心机制:
      1. 数据响应式:通过 Object.defineProperty拦截属性的getter与setter(Vue2)或 Proxy(Vue3)拦截数据的读取和修改,实现数据变化的监听。
      2. DOM 监听:通过事件监听(如 inputchange)捕获用户对视图的操作,同步更新数据,,监听虚拟DOM变化
    • 核心思路都是 “数据驱动视图 + 视图监听更新数据”,联想v- model实现原理
    • 双向绑定原理
      • 数据劫持:通过 Object.defineProperty 监听数据(data)的 get 和 set 操作;
      • 依赖收集:在数据被访问时(get),收集依赖该数据的「Watcher」;
      • 发布更新:当数据被修改时(set),通知所有依赖的「Watcher」更新视图;
      • 视图反馈:通过事件监听(如 input 事件)将用户输入同步回数据,形成双向绑定。
  2. 为什么要两种有定义响应式变量的方式

    • ref 和 reactive 的分工本质是适配 JavaScript 基础类型与引用类型的差异
    • 用 ref 处理基础类型,通过 .value 访问,ref也可以处理引用类型(但会自动转为 reactive 代理)
    const user = ref({ name: 'Tom' }) // 等价于 user.value = reactive({ name: 'Tom' })
    
    • 用 reactive 处理对象 / 数组(复杂结构),直接访问属性。
    • ref支持重新赋值保持响应式,reactive对象赋值后会丢失响应式
  3. ref 为什么js使用变量时,需要.value

    • 这涉及到proxy ,基础类型数据(比如number、string等)等无法被proxy直接代理(Proxy 需要代理对象),ref会把它们包装成对象,这个包装对象可以被 Vue 的响应式系统(Proxy)拦截,从而实现对 value 的读取(get)和修改(set)的监听。
  4. reactive局限性----- reactive()返回一个proxy对象,官方建议使用 ref() 作为声明响应式状态的主要 API

    • 它只能用于对象类型 (对象、数组和如 MapSet 这样的集合类型)。它不能持有如 stringnumber 或 boolean 这样的原始类型;
    • 不能替换对象,替换的话与第一个引用的响应性连接将丢失;
    • 解构变量丢失响应性:响应式对象的属性解构为本地变量时,或者将该属性传递给函数时,将丢失响应性连接
    • reactive响应式丢失解决----避免直接赋值+不解构(使用toRefs()转成ref变量);通过修改属性到达效果;可以使用Object.assign(xx,{...})实现保持响应式;
  5. 自动解包场景

    • 模板「浅层」自动解包,如果 ref 嵌套在普通对象中,不会自动解包(需手动 .value
      • 也可以把它解构出来作为顶级属性,比如const object = { id: ref(1) } 中的id--》const { id } = object就可以在模版中使用{{id}}
    • 当 ref 被嵌套在 reactive 对象中时,访问该属性会自动解包(无需 .value

一些重要的语法

  1. 计算属性computed与属性监听

    • 计算属性值会基于其响应式依赖被缓存;
    • 计算属性的 getter 应只做计算而没有任何其他的副作用,比如不要改变其他状态、在 getter 中做异步请求或者更改 DOM
    • watch:监听reactive会自动开启深度监听(ref需手动开启),vue3新增了watchEffect 会自动追踪回调中使用的响应式数据(隐式监听);侦听响应式对象的属性值需要()=>obj.xxx
  2. 生命周期

    • 生命周期名字加on,去掉了(before)created(==setup执行时机),destroy变成unmount
  3. 组件props(输入) event(输出)

    • 单向数据流:props 是只读的,组件内部不能直接修改,需通过事件通知父组件更新
  4. hooks 逻辑复用,mixin会容易冲突、阅读起来困难

  5. 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。
  6. nextTick 当数据变化时,Vue不会立即更新 DOM,而是将所有更新请求缓存,批量进行更新,nextTick是在DOM 更新完成后(就好像 其实是虚拟DOM计算的结果)执行操作 (这其实跟浏览器的内部处理机制有关,js线程执行会阻塞浏览器渲染进程==DOM更新,Vue框架在其中的作用是它有做一个收集+监听所有数据更新的操作,VUE内部有检测的虚拟DOM的变化,nextTick回调执行在一轮事件循环的末端,所以就算此时浏览器的真实DOM还没有更新,nexttick()里面通过新虚拟DOM可以获取到DOM更新后的结果)

pinia

通过 defineStore 定义一个 Store,第一个参数是唯一的 id(用于区分不同 Store),第二个参数是配置对象(包含 stateactionsgetters); 解构store可避免响应式丢失直接解构 Store 会丢失响应式,需使用 storeToRefs 辅助函数; 优势:

  1. 无需 mutation,直接在 actions 中修改状态,更简单
  2. 完美支持 TypeScript 和组合式 API
  3. 轻量且灵活

自定义指令

生命周期:

  • created:元素初始化时(还未插入 DOM)。
  • mounted:元素插入 DOM 后(最常用,适合初始化操作)。
  • updated:元素更新时(组件更新后)。
  • unmounted:元素从 DOM 中移除时(适合清理操作

路由

vue封装组件的要点

  1. 复用性(适配多种场景):合理设计 Props(输入,明确类型和默认值)与 $emit(输出);多传入少写死;
  2. 可维护性(好懂、好改)+易用性:文档与易用性(清晰注释:组件功能、Props 含义、Events 触发时机需注释)
  3. 扩展性:插槽设计(默认插槽、具名插槽、作用域插槽=父组件定义的插槽中可以访问子组件的数据);支持自定义类名与样式:提供 class 和 style Props,允许用户覆盖默认样式
  4. 其他:样式隔离(局部样式,深度选择器:需要修改子组件样式时,用 ::v-deep(Vue2)或 :deep()(Vue3)穿透 scoped

三、vite/webpack 特点以及原理

webpack

以前的webpack只认识js,通过loader将其他语言转化,plugin是插件,可以扩展webpack的功能

  1. loader:babel-loader 把ES6转成ES5 css-loader:加载css  sass-loader:转化成CSS、eslint-loader, style-loader:css注入js中 vue-loader html-loader
  2. pluginhtml-webpack-plugin :简化创建html文件 clean-webpack-plugin目录清理 HotModulePlugin热更新
  3. webpack构建流程 :初始化配置,加载plugin,实例化compiler,开始编译从entry出发,分析所有模块依赖(如 import/require),调用loader去加载模块(loader转换非JS资源(如 CSS 转 JS 模块)),将模块转化成chunk文件,最后输出到outputdir;
  4. 缺陷:全量打包 无论开发环境(dev)还是生产环境(build),都需要将所有代码(JS、CSS、图片等)递归打包成一个个 “bundle 文件”(如 main.js);开发环境下,项目越大,打包时间越长,启动和热更新速度越慢。

vite

启动速度快 热更新速度快 无需手动配置loader,开发环境和生产环境采用不同策略,优化开发体验:

  1. 开发环境(dev) :不打包,直接利用浏览器原生支持的 ESM(<script type="module">)加载模块。Vite 仅作为 “代理服务器”,接收浏览器请求时,实时转换非 ESM 资源(如将 Vue/React 单文件组件转 ESM、处理 TS),无需等待全量打包,启动和热更新极快。
  2. 生产环境(build) :基于 Rollup 打包(Rollup 比 Webpack 打包体积更小、Tree-Shaking 更彻底),输出优化后的 bundle 文件,兼顾性能和兼容性。
  3. 缺陷:Vite:默认不支持 IE 浏览器(因依赖 ESM,IE 不支持),需额外配置插件

JS

原型

  1. new一个对象

事件循环

四个线程:js线程、处理异步http请求线程+处理定时器线程(执行完毕后把回调函数推入队列中)、管理队列的线程

闭包

proxy

promise

浏览器相关

浏览器引擎/工作原理-------

把浏览器比做一个普通应用,要让它在windows系统运行,你要实现它的主要功能:

  1. 输入一个URL可以获取服务器资源(html+CSS+js),解析这些资源,展示页面
  2. 页面支持
  3. 支持打开多个标签页,页面刷新 收藏等等

兼容性问题

  1. 为什么会有兼容性问题?
    • W3C推出的新特性,各个浏览器版本更新会逐步去支持新特性,但它们的旧版本可能不兼容;
    • 不同的的浏览器使用的内核不一样,对标准的实现存在差异,Chrome/Safari 用 WebKit/Blink,Firefox 用 Gecko,Edge 基于 Blink
  2. 存在哪些兼容性问题?
    • 比如:new Date('2023-13-01')有些浏览器会报错,Safari、IE、Firefox也无法正确解析YYYY-MM-DD格式的日期字符串,而Chrome可以正常处理
    • 一些新出的ES6+语法,旧版本浏览器可能不支持
    • CSS3(animation、transition、圆角、渐变、阴影等等)、HTML5
  3. 如何解决兼容性问题?
    • 可以在 package.json 中添加 browserslist 字段,配置目标浏览器
    • 构建工具中通过babel-loader 把ES6转成ES5
    • 用 Autoprefixer 自动添加 CSS 前缀(如 -webkit-
    • API polyfill,比如让工具(如 core-js)只引入必要的 polyfill,减少代码体积

移动端

NodeJS

TS

如何自己搭建脚手架

算法

设计模式

观察者模式:一对多,被观察者(数据),观察者

AI工具

  1. cursor
    • 通用rules编写(比如技术栈、代码规范、git操作、API请求等等)
    • mcp 让cursor帮你执行操作

对于简历的解读

微信小程序如何对移动端设备进行优化?

  1. 系统适配:不同操作系统的差异性处理:使用uniapp的条件编译,比如针对IOS与安卓系统的导航栏高度、弹窗的层级问题处理;
  2. 屏幕适配:使用rpx单位,结合flex
  3. 微信版本适配:针对低版本微信客户端,用 wx.canIUse 检测 API 兼容性,不支持的做降级处理
  4. 手机品牌适配:比如华为的刘海屏处理,通过uni获取设备参数,去判断做特殊处理 5.性能优化:
    • 优化请求:使用本地存储减少请求、压缩资源
    • 优化首屏加载:分包(控制小程序体积)、图片懒加载(只加载 “用户当前可见区域” 内的图片)、代码Tree Shaking
    • 优化渲染性能:长列表使用虚拟列表、数据批量更新等等

微前端qiankun

  • 主应用(host) :负责整合所有微应用(注册),提供公共的导航、权限、全局状态等基础能力。
  • 微应用(app) :被拆分出来的独立子应用(如首页、商品页、用户中心等),可单独开发、测试、部署。
  • 生命周期:微应用有 bootstrap(初始化)、mount(挂载)、unmount(卸载)等生命周期钩子,可接收从主应用传过来的参数。