Vue系列-3

v-model 是如何实现的?本质是什么?

v-model 本质是v-bind+v-on的语法糖,用于实现数据和视图之间的双向绑定;在组件上本质是通过 prop + $emit 实现的父子通信语法糖。Vue2 默认使用 value 和 input,Vue3 改为 modelValue 和 update:modelValue。

v-model 可以被用在自定义组件上吗?如果可以,如何使用?

v-model 可以用于自定义组件。

在 Vue2 中本质是 value + input 事件的语法糖;

在 Vue3 中本质是 modelValue + update:modelValue 的语法糖。

其核心机制都是通过 prop 传值、通过 $emit 通知父组件,实现父子组件之间的双向数据绑定。

data为什么是一个函数而不是对象?

因为组件是可复用的,会被创建多个实例,如果 data 是对象,所有实例会共享同一个数据对象,导致数据互相污染;使用函数可以为每个组件实例返回一个全新的数据对象,保证状态独立。根实例只有一个,不存在复用问题,因此可以使用对象。

对keep-alive的理解,它是如何实现的,具体缓存的是什么?

keep-alive 是 Vue 内置的抽象组件,用来缓存动态组件或 router-view 中的组件实例,避免组件重复创建和销毁。

它通过缓存组件的 vnode 和 componentInstance,在组件切换时不销毁实例,而是保存状态,下次激活时直接复用。

内部使用 LRU 策略控制缓存数量,可以通过 include、exclude、max 控制缓存规则。

$nextTick 原理及作用

1.$nextTick 的作用

$nextTick 用于在DOM 更新完成之后 执行回调。因为 Vue 的 DOM 更新是异步批量更新的,所以数据变化后,DOM 不会立刻更新,而是等本轮事件循环结束后统一更新。

2.核心原理

nextTick 本质上是利用 JavaScript 的 EventLoop 机制,优先使用 Promise.then 创建微任务,在 DOM patch 完成后执行回调。常用于在数据更新后获取最新 DOM 结构或操作 DOM。

Vue 中给 data 中的对象属性添加一个新的属性时会发生什么?如何解决?

在 Vue2 中,data 对象的属性在实例创建时就被转换为响应式属性。如果动态给对象添加新属性,Vue 无法检测到变化,视图不会更新。解决方法是使用 this.$set(obj, 'newProp', value)Vue.set(obj, 'newProp', value) 来手动将新属性转换为响应式。Vue3 则使用 Proxy,可以自动响应对象属性的新增。

Vue中封装的数组方法有哪些,其如何实现页面更新

在 Vue2 中,由于 Object.defineProperty不能监听数组索引和长度变化,Vue对数组的方法(push、pop、shift、unshift、splice、sort、reverse)进行了封装。每个方法执行时,先调用原生数组操作,然后对新增元素执行响应式处理,最后通过 dep.notify() 通知 watcher 更新页面,实现视图的实时刷新。Vue3 使用 Proxy 后,无需重写数组方法,所有数组变化都可以被拦截。

Vue 单页应用与多页应用的区别

类型 全称 页面加载方式 资源加载 页面切换
SPA Single Page Application 只加载一次主页面 JS/CSS 等资源只需初次加载 切换组件,局部刷新,无整页刷新
MPA Multi Page Application 每次访问新页面都加载新页面 每个页面都需加载对应 JS/CSS 页面整体刷新
方面 SPA MPA
页面结构 单个 HTML 页面 + 前端路由 多个 HTML 页面,每个页面独立
路由方式 前端路由(Vue Router)控制组件显示 后端路由,页面跳转由服务器返回 HTML
用户体验 页面切换流畅,无白屏闪烁 页面切换会整体刷新,有明显闪烁
性能 初次加载大,后续切换快 每次加载页面都需要请求资源,切换慢
SEO 优势 SEO 不友好(需要 SSR 或 prerender) SEO 友好,页面内容直接渲染在 HTML
开发方式 前端主导,组件化开发,API 数据交互 后端主导,每个页面独立开发,逻辑耦合后端
缓存和状态 前端维护状态,数据可缓存 页面刷新后状态丢失,需要后端保存

Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗?

Vue 响应式系统侦测到数据变化后,并不会立即操作 DOM,而是把变化的 watcher 推入异步更新队列,队列中同一 watcher 多次变化会去重,然后在下一个事件循环 tick 中统一执行 DOM 更新。可以使用 this.$nextTick 在 DOM 更新后执行操作。

简述 mixin、extends 的覆盖逻辑

Mixin 是 Vue 提供的可复用组件逻辑机制,通过将生命周期、方法、数据等混入组件,实现代码复用;组件自己的同名选项会覆盖 mixin 的选项,生命周期钩子会先执行 mixin 的,再执行组件自身的。

mixin 和 extends 本质都是通过 mergeOptions 进行选项合并。

合并顺序是 extends → mixins → 组件自身。

生命周期钩子会合并成数组,并按顺序执行;

data 会执行函数后合并对象,冲突时组件优先;

methods、computed、props 等选项会直接覆盖,组件优先级最高;

watch 如果重名会合并成数组。

描述下Vue自定义指令

Vue 自定义指令是对普通 DOM 元素进行底层操作的扩展机制,适用于需要直接操作 DOM 的场景,比如自动聚焦、图片懒加载、滚动监听或集成第三方插件。

自定义指令可以全局注册,也可以在组件中局部注册。

在 Vue2 中,指令包含 bind、inserted、update、componentUpdated、unbind 等生命周期钩子,可以在不同阶段对元素进行操作。钩子函数会接收 el、binding、vnode 等参数。

一般建议自定义指令只用于操作 DOM,而不要直接修改组件内部数据。

子组件可以直接改变父组件的数据吗?

子组件不能直接修改父组件传递过来的数据(props)。

Vue 采用的是单向数据流 ,数据只能从父组件流向子组件。如果子组件直接修改 props,Vue 会在控制台给出警告。这样设计是为了保证数据流清晰,避免组件之间状态混乱,方便维护和调试。如果子组件需要修改父组件的数据,应该通过 $emit 触发一个自定义事件,由父组件在事件回调中修改数据。

对 React 和 Vue 的理解,它们的异同

React 和 Vue 都是用于构建用户界面的前端框架,核心思想都是组件化和数据驱动视图,并且都使用 Virtual DOM 来提高渲染性能。它们的核心库都只关注视图层,路由、状态管理等功能通过生态库扩展,属于"核心精简、生态完善"的设计思路。

对比维度 Vue React
设计思想 偏声明式 + 响应式 偏函数式编程
数据流 单向数据流(支持 v-model 语法糖) 单向数据流
响应式原理 Vue2:Object.definePropertyVue3:Proxy 精准依赖收集 状态变化后组件重新执行,通过 diff 比较 Virtual DOM
更新机制 依赖追踪,细粒度更新 组件重新 render,再做 Virtual DOM diff
模板写法 Template 模板,接近 HTML JSX,本质是 JavaScript
逻辑复用方式 Vue2:mixinVue3:Composition API HOC、Hooks
性能优化方式 默认做依赖追踪优化 需要手动优化(memo、useMemo、useCallback)

assets和static的区别

在 Vue CLI 项目中,assets和static都是用来存放静态资源的,比如图片、字体、样式文件等。

对比项 assets static
是否参与打包 会被 webpack 处理 不会被 webpack 处理
是否压缩/优化 会压缩、hash命名、转 base64 原样拷贝
引用方式 通过 import 或 require 通过绝对路径访问
缓存策略 文件名带 hash,利于缓存控制 文件名固定
适用场景 需要参与构建的资源 不需要处理的资源

delete和Vue.delete删除数组的区别

方法 对数组的影响 对视图更新
delete arr[index] 只是把对应索引置为 undefined,数组长度不变,索引不改变 不会触发 Vue 视图更新
Vue.delete(arr, index)arr.splice(index,1) 删除指定索引的元素,数组长度减 1,后面的元素索引自动前移 会触发 Vue 视图更新

vue如何监听对象或者数组某个属性的变化

Vue2 监听对象或数组属性变化,新增属性要用 this.$set,数组修改要用重写的数组方法(如 splice、push,Vue 对数组原型方法做了拦截,执行这些方法时会触发依赖更新(dep.notify()),视图自动刷新),这样才能触发响应式更新。

对SSR的理解

SSR 就是服务端渲染 ,它把 Vue 组件在客户端渲染成 HTML 的工作放到服务端去完成,然后把生成好的完整 HTML 页面直接返回给浏览器。
优势

SEO 更友好:搜索引擎爬虫可以直接抓取完整的 HTML 内容,而不依赖 JavaScript 执行。

首屏渲染更快:浏览器可以立即显示页面内容,提升用户体验,尤其是移动端或网络较慢的情况下。
缺点

生命周期限制:服务器端没有 DOM,只有 beforeCreate 和 created 钩子可用,不能操作 mounted 或直接访问 DOM。

外部库限制:某些依赖浏览器 API 的第三方库需要特殊处理或不能直接使用。

服务端压力增加:每次请求都需要服务器渲染页面,增加了服务器负载和开发复杂度。

Vue的性能优化有哪些

编码阶段。我们尽量减少 data 中的数据量,因为每个属性都会被 Vue 劫持收集 watcher,数据越多渲染开销越大。列表渲染时,要避免 v-if 和 v-for 连用,长列表可以结合虚拟滚动或者懒加载。组件切换时,可以用 keep-alive 缓存不活跃组件,减少重复渲染。事件绑定可以用事件代理,路由组件可以用懒加载或异步组件,此外防抖节流和图片懒加载也是常用手段。

SEO 优化。Vue 的预渲染或者服务端渲染 SSR 可以让首屏更快,同时改善搜索引擎抓取。

打包优化。生产环境可以压缩代码、使用 Tree Shaking 去掉无用代码,利用 CDN 加载第三方库,抽离公共文件,提高缓存利用率,多线程打包提升构建速度。

用户体验优化。可以做骨架屏、PWA、缓存策略和开启服务端 Gzip 压缩,让页面加载更快、体验更顺畅。

v-if v-for哪个优先级更高?如果同时出现,应如何优化?

在 Vue 中,v-for 的优先级高于 v-if。也就是说,如果同时出现在一个节点上,Vue 会先执行循环生成每一项,再对每一项执行 v-if 条件判断。这会导致即使很多项最终不渲染,循环也已经执行了,浪费性能。

如果条件是针对整个列表的,可以把 v-if 放在外层,用一个 <template> 包裹,先判断条件再执行 v-for 循环。

如果条件是针对单个循环项的,最好用计算属性提前过滤掉不需要显示的元素,让循环只遍历需要渲染的项。

相关推荐
沛沛老爹1 小时前
Vue3+TS实战:基于策略模式的前端动态脱敏UI组件设计与实现
前端·ui·vue3·数据安全·策略模式·动态渲染·前端脱敏
陈随易1 小时前
CDN的妙用,隐藏接口IP,防DDOS攻击
前端·后端·程序员
明月_清风1 小时前
单点登录(SSO)在前端世界的落地形态
前端·安全
九丝城主2 小时前
1V1音视频对话2--Web 双浏览器完整通话测试(强制 relay)
前端·音视频
C澒2 小时前
以微前端为核心:SLDSMS 前端架构的演进之路与实践沉淀
前端·架构·系统架构·教育电商·交通物流
明月_清风2 小时前
OAuth2 与第三方登录的三个阶段(2010–至今)
前端·安全
We་ct2 小时前
LeetCode 138. 随机链表的复制:两种最优解法详解
前端·算法·leetcode·链表·typescript
dcmfxvr2 小时前
【无标题】
java·linux·前端
无巧不成书02182 小时前
React Native 深度解析:跨平台移动开发框架
javascript·react native·react.js·华为·开源·harmonyos