Vue系列-4

说一下Vue的生命周期

Vue 的生命周期指的是一个 Vue 实例从创建到销毁的完整过程,大致可以分为创建 → 挂载 → 更新 → 销毁四个阶段。

创建阶段

beforeCreate:实例刚创建,此时数据响应式、computed、watch 等都还没初始化,基本拿不到 data。

created:实例创建完成,data、methods、computed、watch 都已经可用,但DOM还没有生成。一般在这里发送请求(ajax)或初始化数据。

挂载阶段

beforeMount:模板已经编译成 render 函数,但还没真正渲染到页面。

mounted:DOM已经挂载完成,可以访问 $el,也可以进行DOM 操作。常用于操作DOM、初始化第三方库。

更新阶段

当响应式数据变化时触发:

beforeUpdate:数据变了,但页面还没更新。

updated:DOM 已经更新完成。一般不建议在这里再次修改数据,否则可能造成无限更新。

第四阶段:销毁阶段

beforeDestroy:实例销毁前,组件仍可使用。常用于清除定时器、解绑事件、取消请求。

destroyed:组件完全销毁,事件监听和子组件全部移除。

created和mounted的区别

它们最大的区别在于 DOM 是否已经生成。

created:在实例创建完成后调用,数据已经完成响应式初始化,data、methods、computed、watch 都可以使用,DOM 还没有挂载,访问不到 $el

mounted:在组件模板已经渲染并挂载到真实 DOM 后调用,可以访问 $el,可以操作真实 DOM

keep-alive 中的生命周期哪些

keep-alive 是Vue的内置组件,用于缓存组件实例,避免组件在切换时被重复创建和销毁,从而提升性能并保留组件状态。当组件被 keep-alive 包裹后,会新增两个生命周期:

activated:组件从缓存中重新显示时触发,相当于组件被"重新进入页面"常用于:重新发送请求,刷新页面数据,恢复定时器

deactivated:组件被切换离开,但没有销毁时触发,组件进入缓存,常用于:清除定时器,暂停监听或动画

Vue 组件通信

1.父子组件通信

props / $emit

父 → 子:通过props传递数据

子 → 父:通过$emit触发事件通知父组件修改数据

这是 Vue 提倡的单向数据流。使用场景:绝大多数业务开发。

ref / $refs:父组件通过ref获取子组件实例,直接调用方法或访问数据。调用子组件方法,表单校验,控制弹窗

provide / inject:深层组件传值,避免 props 层层传递(prop drilling),默认不是响应式(Vue2)。

2.兄弟组件通信

EventBus(事件总线),通过一个公共 Vue 实例进行事件派发:Vue3不使用了

3.跨层级组件通信

attrs / listeners,用于多层组件透传props和事件。常见场景:A → B → C,B 不处理数据,直接透传给 C。

4.任意组件通信

就是Vuex/Pinia

路由的hash和history模式的区别

Vue Router 有两种路由模式:hash 模式和 history 模式,它们主要区别在于 URL 形式和实现原理不同。

hash 模式的 URL 会带一个 #,比如 /#/user,它是通过监听浏览器的 hashchange 事件实现路由切换的。hash 变化不会向服务器发送请求,所以不需要后端配合,兼容性也很好,这是Vue 默认的模式。

history 模式基于HTML5的History API,比如 pushState,URL 看起来像正常路径,没有 #,更美观,也更利于 SEO。不过刷新页面时浏览器会向服务器请求当前路径,如果后端没有做重定向配置,就会出现 404。

一般来说,后台管理系统常用 hash 模式,而官网或需要SEO的项目更适合history模式。

route 和 router 的区别主要是:

route 是路由信息对象,router 是路由实例对象。

$route 用来获取当前路由的信息,比如 path、params、query、name等,它是只读的,通常用于获取参数或监听路由变化。

$router 是整个 Vue Router 的实例,主要用来进行路由操作,比如 push、replace、go,用于页面跳转或注册导航守卫。

route 负责"拿数据",router 负责"做跳转"。

Vue-router跳转和location.href有什么区别

location.href,会刷新页面,浏览器会重新向服务器请求资源。页面状态会丢失,整个应用重新加载。

Vue-Router(this.$router.push() 或 <router-link>),不刷新页面,属于前端路由的跳转。Vue-Router 会用 diff 算法更新视图,只渲染变化的部分 DOM,性能更好。本质上,history 模式下是封装了 history.pushState(),hash 模式下是修改 location.hash。

params和query的区别

在Vue-Router中,params和query都可以传递参数,但方式不同。params需要在路由中定义动态路径(如 /user/:id),通过name跳转,参数通过this.route.params 获取,不会显示在 URL 上,但刷新页面会丢失。query 是普通路由传参(如 /user?id=123),通过 path 跳转,参数通过 this.route.query 获取,会显示在 URL 上,刷新页面参数不会丢失。

对前端路由的理解

前端路由的核心是在单页面应用(SPA)中,通过 URL 来标识不同的视图,实现无需刷新页面即可切换内容的效果。早期网页是多页面模式,每次切换页面都会刷新整个页面,体验较差;SPA 的出现解决了页面无刷新更新的问题,但带来了"URL 不变、用户操作无法定位"和"SEO 不友好"的问题。

前端路由通过在浏览器端感知URL的变化,将不同的 URL 映射到不同的视图上,即便刷新页面,也能根据 URL 渲染对应内容。同时,前端路由会拦截刷新操作,避免服务器无意义的请求,从而实现了 SPA 下的导航、前进后退和状态保持。常见实现方式有hash模式和history模式,分别通过 # 或 HTML5 History API来管理URL与视图的对应关系。

Vuex的原理

Vuex 本质上是 Vue 的集中式状态管理方案 ,用于管理多个组件之间共享的数据。它的核心思想是:用一个全局 Store 统一管理状态,并通过单向数据流保证数据变化可预测。组件不能直接修改 state,而是必须按照固定流程进行数据修改:组件通过 dispatch 触发 action,action 主要处理异步逻辑,然后通过 commit 提交 mutation,mutation 再去同步修改 state。当 state 发生变化时,由于 Vue 的响应式机制,依赖该数据的组件会自动重新渲染。

Vuex中action和mutation的区别

在 Vuex 中,mutation 和 action 都是用来修改状态流程的一部分,但职责不同。

mutation 主要负责修改 state,并且必须是同步操作,组件通过 commit 来触发 mutation。这样做是为了保证状态变化是可追踪的,方便调试。

action 主要负责 处理业务逻辑和异步操作,比如请求接口、定时任务等。action 不能直接修改 state,而是通过 commit 去调用 mutation 来间接修改数据,组件通过 dispatch 来触发 action。

Vuex和localStorage的区别

存储位置不同

Vuex:存储在内存中,读取快,刷新页面会丢失数据。

localStorage:存储在浏览器本地,以字符串形式保存,刷新页面不会丢失数据。

响应性和用途

Vuex:支持响应式,适合组件间共享和管理状态。

localStorage:不支持响应式,适合跨页面保存固定数据。

应用场景

Vuex:组件之间传值和状态管理。

localStorage:长期保存数据或跨页面传递数据。

Redux 和 Vuex 有什么区别,它们的共同思想

Vuex 和 Redux 都是前端状态管理库,本质上都是把数据从视图中抽离出来,实现单一数据源和可预测的状态变化。不同点是:Vuex 用 mutations 替代 Redux 的 reducer,不需要 switch,直接在 mutation 里修改 state;Vuex 利用 Vue 的响应式特性,修改 state 后组件会自动重新渲染,而 Redux 需要手动订阅更新;Vuex 弱化了 dispatch 和 reducer,只需通过 commit 改变状态,更加简单直观。

Vuex 有哪几种属性

Vuex 是 Vue 的状态管理工具,它主要有五种属性:state 存放基本数据,getters 从 state 派生数据,mutations 用于同步修改 state,actions 用来触发 mutations 并支持异步操作,modules 则用于模块化管理状态,方便大型项目维护。整个流程是组件通过 dispatch 或 commit 调用 actions 或 mutations 改变 state,state 改变后,组件会响应式更新视图,从而实现全局状态的可预测管理。

Vuex和单纯的全局对象有什么区别?

Vuex 和单纯的全局对象最大的区别在于响应式和可预测管理:Vuex 的状态存储是响应式的,组件读取 store 中的状态时,如果状态发生变化,组件会自动高效更新;同时,Vuex 不允许直接修改 state,必须通过 commit 提交 mutation 来改变状态,这样可以方便地跟踪每一次状态变化,保证数据流可预测且易于维护,而单纯的全局对象无法做到这些**。**

为什么 Vuex 的 mutation 中不能做异步操作?

Vuex 中的 mutation 不能做异步操作,因为 mutation 是唯一改变 state 的途径,它必须同步执行以保证每次状态变化都是可追踪的。异步操作会通过 action 提交 mutation,这样可以让状态变化有明确的时间点,使 devtools 能够记录快照,实现状态追踪和 time-travel 调试。如果 mutation 支持异步操作,就无法准确知道状态何时更新,调试和追踪都会变得困难。

Vue3.0有什么更新

Vue 3 相比 Vue 2 的主要更新是:响应式机制由 Object.defineProperty 改为 Proxy,支持更多数据类型;模板优化了作用域插槽和 render 函数,提升渲染性能;组件写法更易于 TypeScript 和组合式 API 使用;支持 Fragment、Portal、多根节点渲染;并且体积更小,可 tree-shaking,性能和扩展性都更好。

defineProperty和proxy的区别/为什么Vue3要用Proxy

Vue 2 用 Object.defineProperty 逐个属性设置 getter/setter 来实现响应式,但无法检测新增或删除的属性,也无法监听数组索引和长度变化;Vue 3 用 Proxy 直接代理整个对象,不用 Vue.set/delete 就能检测属性新增或删除,能监听属性增删和数组变化,性能更好,支持更多数据类型。

Composition API与React Hook很像,区别是什么

Composition API 和 React Hook 都是组合式逻辑复用的方案,但区别在于:React Hook 每次组件重渲染都要调用 Hook,需要在顶层固定顺序、手动管理依赖;而 Vue 的 Composition API 利用响应式系统,只在 setup 调用一次,可在循环或条件中使用,依赖收集自动完成,性能更优且使用更灵活。

虚拟DOM的理解

虚拟DOM其实是一个轻量级的 JavaScript 对象,用来描述真实 DOM 的结构。每次数据变化时,Vue 会先生成新的虚拟 DOM,再和之前的虚拟 DOM 进行 diff 比较,只把变化的部分更新到真实 DOM,从而减少重排和重绘,提升性能。本质上,虚拟 DOM 是对 DOM 的抽象,它让前端渲染跨平台成为可能,也让开发者无需手动操作 DOM,提高了开发效率和可维护性。

虚拟DOM的解析过程

构建虚拟 DOM:首先将要渲染的 DOM 树抽象成 JavaScript 对象,每个节点包含 tag、props、children 等信息,形成一棵对象树。

Diff 比较:当数据变化时,重新生成一棵新的虚拟 DOM 树,然后和旧的虚拟 DOM 树进行比较,找出差异。

更新真实 DOM:将差异部分应用到真实 DOM 中,只更新变化的节点,从而减少重排重绘,提升性能。

为什么要用虚拟 DOM:

保证性能:通过在 JS 层构建虚拟 DOM 树并进行 Diff 对比,只更新变化的节点,避免频繁操作真实 DOM 的重排重绘,提高渲染效率,即便不手动优化也能获得较好性能。

跨平台:虚拟 DOM 是 JS 对象,可以方便地在不同平台渲染,如服务端渲染(SSR)、移动端框架(uni-app)等,实现跨平台开发。

Diff 算法原理:

在虚拟 DOM 更新时,Vue 会先判断新旧节点是否为同一节点,如果不是就直接替换;如果是同一节点,则对节点的属性和子节点进行比对。对子节点的比对只在同一层级进行(不跨级比较),包括新增、删除和移动操作,匹配到相同子节点则递归对比。通过这种策略,时间复杂度从 O(n³) 降到 O(n),只对必要部分进行最小化更新,从而提升渲染性能。

Vue 中 key 的作用:

key 用于虚拟 DOM 的唯一标识,保证节点更新时能准确、高效地复用或替换。在 v-if 场景中,key 可以避免元素被复用,确保切换时状态重置;在 v-for 场景中,key 用于追踪列表中每个元素的身份,使 Vue 能够高效地比对和更新虚拟 DOM,从而减少不必要的 DOM 操作,提高渲染性能。

相关推荐
Ai runner1 小时前
Show call stack in perfetto from json input
java·前端·json
晴殇i1 小时前
前端防调试攻防战:如何保护你的JavaScript代码不被“偷窥”?
前端·javascript·面试
谦虚的酷猫2 小时前
SpiderDemo部分题目分析
javascript·网络爬虫
清粥油条可乐炸鸡2 小时前
tailwind-variants基本使用
前端·css
csdn飘逸飘逸2 小时前
Autojs基础-app(应用)
javascript
2301_816997882 小时前
虚拟DOM与Diff算法
前端·vue.js·算法
清粥油条可乐炸鸡2 小时前
Vite创建react项目
前端·vue.js
2301_816997882 小时前
Webpack基础
前端·webpack·node.js
yuki_uix2 小时前
WebSocket 连上了,然后呢?聊聊实时数据的"后半场"
前端·websocket