前端面经-Vue

标题

1、双向绑定原理,手撕简单源码(vue响应式原理)

Vue的双向数据绑定是通过数据劫持结合发布者订阅者模式来实现的

  • 实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可以拿到最新值并通知订阅者
  • 实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
  • 实现一个watcher,作为连接Oberver和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行绑定的相应回调函数,从而更新视图
  • MVVM入口函数,整合以上三者

在这里插入图片描述
描述
Vue数据双向绑定原理是通过数据劫持结合发布者-订阅者模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图
通过Object.defineProperty()来劫持各个属性的setter, getter,在数据发生变动时通知Vue实例,触发相应的getter和setter回调函数。
当把一个普通 Javascript 对象传给Vue 实例来作为它的 data 选项时, Vue 将遍历它的属性,用Object.defineProperty将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

2、vue的优点

  • 轻量级的框架
  • 双向数据绑定
  • 组件化
  • 视图,数据,结构分离
  • 虚拟dom

3、请谈谈Vue中的MVVM模式

MVVM全程是Model-View-ViewModel

vue是以数据为驱动的,vue自身将DOM和数据进行绑定,一旦创建绑定,dom和数据将保持同步。每当数据发生变化,dom会跟着变化。ViewModel是Vue的核心,它是Vue的一个实例。

DomListeners和DataBindings是实现双向绑定的关键。DOMListenners监听页面所有View层DOM元素的变化,当发生变化,Model层的数据随之改变;DataBindings监听Model层的数据,当数据发生变化,View层的DOM元素随之变化。

4、渐进式框架的理解

“渐进式框架”就是用你想用或者能用的功能特性,你不想用的部分功能可以先不用。vue不强求你一次性接受并使用它的全部功能特性。

5、vue中双向数据绑定是如何实现的

view更新data其实可以通过时间监听即可,比如input标签监听“input”事件就可以实现了

通过Object.defineProperty()对属性设置一个set函数,当数据改变了就会触发这个函数,所以我们只要将一些需要更新的方法放在里面就可以实现data更新view了。

6、虚拟DOM

virtual dom 其实就是一颗以js对象(VNode节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实DOM的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。

6.1diff算法

找出有必要更新的节点更新,没有更新的节点就不要动。这其中的核心就是如何找出哪些更新哪些不更新,这个过程就需要diff算法来完成
怎么做到复杂度从o(n^3)降低到o(n)
标准diff算法:o(n^3) 树的最小距离编辑算法(找到最少的改动路径)算出来的(待了解)考虑到前端操作很少跨级别修改节点,通常都是修改节点属性,及调整子节点,所以只比较同层级的节点。就将复杂度降到了n
patch过程:
1 对比新节点是否存在,不存在插入新节点
2 对比老节点是否存在,不存在删除老节点
3 对比新节点与老节点是否相同,如果不同则删除老节点,插入新节点
4 如果新老节点相同(tag,key等),则执行patchVNode,如果是文本的话就处理,然后对比children。
diff重点
对比children,若老的有新的没则删除,若新的有老的没,则新增。
若都有children,先头头比较,然后尾尾比较,头尾,尾头比较(主要是为了快速处理reverse的情况),
如果相同,则执行patchVNode进行children的对比,如果不同,则会对老节点进行map处理,在里面按照key来找新节点,如果找到了,则patchvnode,否则新建,没有key的话就新建
3.0中diff的差异
预处理及最长递增子序列

7、created和mounted的区别

created

实例创建完成,可以访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到$el属性, $ref属性内容为空数组。

mounted

实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问,常用与获取VNode信息和操作,Ajax请求。

8、computed和watch的区别

computed
computed看上去是方法,但是实际上是计算属性,它会根据你所依赖的数据动态显示新的计算结果。计算结果会被缓存,computed的值在getter执行之后是会缓存的,只有在它依赖的属性值改变之后,下一次获取computed的值才会重新调用对应的getter来计算。

watch

watcher更像是一个data的数据监听回调,当依赖的data的数据变化,执行回调,在方法中会传入newVal和oldVal。可以提供输入值无效,中间值等场景。Vue实例将会在实例化的时候调用$watch(),遍历watch对象的每一个属性。如果你需要在某个数据变化时候做一些事情,使用watch

总结

如果一个数据需要经过复杂计算就用computed。
如果一个数据依赖于其他数据,那么把这个数据设计为computed的

如果一个数据需要被监听并且对数据做一些操作就用watch。
如果你需要在某个数据变化的时候做一些事情,使用watch来观察这个数据变化。

9、vue3新特性,proxy和defineProperty的区别

  1. Object.defineProperty只能劫持对象的属性,而 Proxy 是直接代理对象。
    由于 Object.defineProperty 只能对属性进行劫持,需要遍历对象的每个属性,
    如果属性值也是对象,则需要深度遍历。而 Proxy 直接代理对象,不需要遍历操作。

  2. Object.defineProperty对新增属性需要手动进行 Observe。
    由于 Object.defineProperty劫持的是对象的属性,所以新增属性时,需要重新遍历对象,
    对其新增属性再使用 Object.defineProperty 进行劫持。

也正是因为这个原因,使用 Vue 给 data 中的数组或对象新增属性时,
需要使用 vm.$set 才能保证新增的属性也是响应式的。

9.1proxy应用实例

1. 数据验证
在设置对象属性时,使用 Proxy 可以对输入的值进行验证,确保其符合特定的规则。
解释:创建了一个 person 对象的代理 personProxy,在 set 拦截器中对 age 和 name 属性的赋值进行验证。如果赋值不符合规则,会抛出错误。
2. 访问控制
可以使用 Proxy 限制对对象某些属性的访问,只有满足特定条件的用户才能访问。
解释:代码创建了一个 secretData 对象的代理 secretProxy,在 get 拦截器中根据 restrictedAccess.canAccess 的值来决定是否允许访问 password 属性。
3. 日志记录
在对象属性被访问或修改时,使用 Proxy 记录相关的日志信息。
解释:通过 get 和 set 拦截器,在访问和修改 data 对象的属性时,会记录相应的日志信息。
4. 函数调用拦截
Proxy 不仅可以用于对象,还可以用于函数,对函数的调用进行拦截和增强。
解释:创建了函数 add 的代理 addProxy,在 apply 拦截器中记录函数调用的参数和返回值。
5. 数组边界检查
对于数组,可以使用 Proxy 检查访问的索引是否越界。
解释:创建了数组 arr 的代理 arrProxy,在 get 和 set 拦截器中检查索引是否越界,如果越界会输出提示信息。

10、MVVM和mvc的差别

  • MVC中Controller演变成MVVM中的ViewModel
  • MVVM通过数据来显示视图层而不是节点操作
  • MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验等问题。

11、父子通信(传值

通信
一.父组件向子组件传递值使用props;
二.子组件向父组件传递值用this. $emit()
三.组件与组件值引用可采用vuex.
四.vuex是一个专为vue. js应用程序开发状态管理模式。集中式管理所有组件的状态。
五.利用插槽子组件向父组件传值

12、非父子通信(多个vue实例传值)(vuex)

如何实现一个vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。简单来说就是:应用遇到多个组件共享状态时,使用vuex。

场景:多个组件共享数据或者是跨组件传递数据时

vuex的流程

页面通过mapAction异步提交事件到action。action通过commit把对应参数同步提交到mutation,mutation会修改state中对应的值。最后通过getter把对应值跑出去,在页面的计算属性中,通过,mapGetter来动态获取state中的值

12.1为什么要commit改变状态

通过commit 提交 mutation 的方式来修改 state 时,vue的调试工具能够记录每一次state的变化,这样方便调试。但是如果是直接修改state,则没有这个记录。

12.2同级传参的两种方式

1.query穿参,或者params传参
使用 this.KaTeX parse error: Expected '}', got 'EOF' at end of input: … '参数值'}) this.router.push({name: ‘/’, params: {参数名: ‘参数值’})
注意1: 使用params时不能使用path
接收: var a = this. r o u t e . q u e r y . 参数名 v a r b = t h i s . route.query.参数名 var b = this. route.query.参数名varb=this.route.params.参数名
注意2:实用params去传值的时候,在页面刷新时,参数会消失,用query则不会有这个问题。

13、生命周期

生命周期

概念
Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载DOM-渲染、更新-渲染、卸载等一系列的过程,我们称这是 Vue 的生命周期。

初始化显示

beforeCreated
created
beforeMounted
mounted

更新
beforeUpdate
updated

销毁
beforeDestrory
destrory

14、vue中key的作用

key的作用是为了在diff算法执行时更快找到对应的节点,提高diff速。

key具有唯一性

vue中循环需加 :key = “唯一标识“,唯一表示可以是item里面id index等,因为vue组件高度复用增加key可以标识组件的唯一性,为了更好的区别各个组件key的作用主要是为了高校的更新虚拟DOM

15、v-if和v-show区别

  • 控制手段不同
  • 编译过程不同
  • 编译条件不同
    控制手段:v-show隐藏则是为该元素添加css–display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除

编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换

编译条件:v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染

v-show 由false变为true的时候不会触发组件的生命周期

v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法

性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

使用场景

v-if 相比 v-show 开销更大的(直接操作dom节点增加与删除)

如果需要非常频繁地切换,则使用 v-show 较好

如果在运行时条件很少改变,则使用 v-if 较好

#参考文献

16、vue-router原理,路由如何跳转

window.location的hash方法是干嘛用的
改变location.hash会在浏览器的访问历史中增加一个记录,使用后退键时可以回到上一个浏览位置。利用这一点就可以解决ajax中无访问状态的问题,配合#和历史记录,就可以在无刷新的ajax中顺利往返于各个访问状态。

我们都知道,单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-rouetr在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;根据mode参数来决定采用哪一种方式。

1、Hash模式:
hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;

2、History模式:
HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL,就是利用 history.pushState API 来完成 URL 跳转而无须重新加载页面

通常情况下,我们会选择使用History模式,原因就是Hash模式下URL带着‘#’会显得不美观

但当用户直接在用户栏输入地址并带有参数时: Hash模式:xxx.com/#/id=5 请求地址为 xxx.com,没有问题; History模式: xxx.com/id=5 请求地址为 xxx.com/id=5,如果后端没有对应的路由处理,就会返回404错误;

在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。 给个警告,因为这么做以后,你的服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,你应该在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。或者,如果你使用 Node.js 服务器,你可以用服务端路由匹配到来的 URL,并在没有匹配到路由的时候返回 404,以实现回退。

17、 vuex数据流向,mutation和action

1、流程顺序

“相应视图—>修改State”拆分成两部分,视图触发Action,Action再触发Mutation。

2、角色定位

基于流程顺序,二者扮演不同的角色。

Mutation:专注于修改State,理论上是修改State的唯一途径。

Action:业务代码、异步请求。

3、限制

### Vue.js 前端开发试经验与知识点总结 #### 一、基础知识 Vue.js 是一个渐进式的 JavaScript 框架,其核心库专注于视图层。开发者可以轻松集成其他库或现有项目[^3]。以下是常见的基础概念: - **MVVM模式**:Vue 实现了 MVVM(Model-View-ViewModel)架构,其中 ViewModel 负责连接 Model 和 View。 - **数据绑定**:Vue 提供双向数据绑定机制,通过 `v-model` 指令实现表单输入和应用状态之间的同步[^1]。 - **指令**:Vue 的模板语法允许使用自定义属性称为指令,用于操作 DOM。例如 `v-if`, `v-for`, `v-bind` 等。 #### 二、组件化开发 组件是 Vue 应用的核心组成部分之一。了解如何设计和管理组件非常重要: - **Props 和 Events**:父组件可以通过 props 向子组件传递数据;子组件则利用事件向上传递消息给父组件。 - **Scoped CSS/Style**:为了防止样式污染,在编写组件时推荐使用 scoped styles 或者单独封装 css 文件引入到组件内部。 - **生命周期钩子函数**:熟悉各个阶段的钩子方法如 created, mounted, updated 及 destroyed 对调试以及逻辑控制非常有帮助。 #### 三、路由与状态管理 随着项目的复杂度增加,合理配置路由规则并有效处理全局状态变得尤为关键: - **Vue Router**:这是官方支持的一个插件用来实现 SPA (Single Page Application),需掌握动态路由匹配、导航守卫等功能[^2]。 - **Vuex**:作为集中式存储解决方案,它可以帮助我们跨多个组件共享状态信息,并保持一致性。 #### 四、性能优化技巧 在实际工作中,提升用户体验往往依赖于良好的性能表现: - 使用懒加载技术减少初始页大小; - 利用 keep-alive 缓存经常访问但不常改变的部分界内容; - 图片资源按需加载或者压缩尺寸以加快渲染速度。 #### 五、测试与部署策略 最后一步也是至关重要的环节就是确保代码质量并通过自动化流程发布上线版本: - 单元测试覆盖主要业务逻辑验证正确性; - E2E 测试模拟真实用户行为检查整体交互流畅程度; - Webpack/Babel 工具链配合 CI/CD 平台完成持续集成与交付工作流设置。 ```javascript // 示例代码展示简单的 Vue 组件结构 <template> <div class="example"> {{ message }} </div> </template> <script> export default { data() { return {message: 'Hello world!'} } } </script> <style scoped> .example{ color:red; } </style> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值