Vue面试经验

devtools/2024/11/14 3:08:29/

Vue编译时声明周期的执行顺序

Vue中父子组件渲染顺序(同步引入子组件:import Son from ‘@/components/son’ )

父子组件编译时的生命周期执行顺序
在这里插入图片描述
这里修改data数据时也修改了dom,如过知识通过按钮对数据进行++操作,那么没有修改dom,也就不会调用beforeupdate和updated生命周期
1.beforeUpdate()是针对视图层的,只有页面中渲染的数据发生改变或者渲染,才会触发这个生命周期函数
2.updated()中修改数据(在视图层进行了展示)是会触发beforeUpdate()的

修改父组件的视图数据
在这里插入图片描述

修该子组件的视图数据
在这里插入图片描述

Vue中父子组件渲染顺序(异步引入子组件:const Son = () => import(‘@/components/son’) )

在这里插入图片描述

组件的通讯方式有哪些

父子组件通信
1.父组件使用自定义属性向子组件传递数据(单向数据流),子组件使用props接受父组件传递过来的数据
2.子组件使用事件向父组件传递数据:$emit('事件名','传递的数据'...)
3.父组件使用v-model语法糖向子组件通信(双向绑定,子组件可以修改):相当于父组件使用了自定义属性value,子组件使用$emit('input','xxx')用父组件传递数据
4.sync修饰符:父传子没什么变化,子传父不需要使用事件接受(双向绑定,类似v-model,不过自定义属性名和变量名相同) $emit('update:属性名',‘传递的数据’)
父组件向后代组件通信

依赖注入(传递的对象是响应式的数据,传入的其他格式的数据是非响应式的)
(provide和inject)

非父子组件通信
使用事件总线(创建事件总线之后,使用$emit发送,使用$on接收)

Vuex

Vuex的属性和方法
// 3. 创建 store 实例对象
const store = new Vuex.Store({/* 这里配置Vuex *///state属性的值是一个对象,用来存储全局共享的数据strict: true,  //开启vue严格模式,不允许在组件中直接修改state数据state: {//在组件中通过 $store.state.属性名调用age: 20,username: 'zhangsan'},mutations:{ //放同步方法,用来更新state中的数据//组件中通过 $store.commit(‘方法名’,参数值)调用updateAge(state,newVal){//第一个参数是固定的,表示实例中的state对象//第二个参数及后续参数,需要调用时传递过来}},actions:{ //放异步方法,actions不能直接修改state数据,可以通过调用mutations中的方法修改state数据
//组件中通过$store.dispatch(‘方法名’,参数值)
update(store,newval){
//第一个参数store是固定的,表示当前的store对象,通过它可以很方便的mutations中的方法
//第二个参数及后续参数,需要调用时传递过来
store.commit('方法名',val)
}
}getters:{//getter是vuex中的计算属性,但是不支持set修改
//组件中通过$store.getters.方法名 调用
isAllDone(state){
//第一个参数state是固定的,表示前面的state对象,通过它可以很方便的找到state中的属性
return xxx
}
}})

可以通过Vuex 提供了 mapState、mapGetters、mapMutations、mapActions 四个方法,使用他们,也可以在组件中直接使用Vuex。
还有使用模块化思想

为什么不能直接修改state的值

因为state是实时更新的,假如可以直接修改state,当你异步对state进行操作时,还没执行完,这时候如果state已经在其他地方被修改了,这样就会导致程序存在问题了。mutations无法进行异步操作,所以state要同步操作,通过mutations的方式限制了不允许异步。

Vue2的双向数据绑定原理

通过数据劫持实现数据的响应式更新,通过发布-订阅模式(Watcher)实现数据和视图之间的双向绑定。当数据发生变化时,会通知订阅者更新视图,保持数据和视图的同步。这种机制使得Vue能够实现高效的数据绑定和视图更新,提高开发效率和用户体验。

步骤

1.数据劫持(Object.defineProperty):创建实例时,Vue通过Object.defineProperty方法对data对象的属性进行劫持,当访问或修改属性值时,会触发getter和setter函数。在getter函数中收集依赖(将Watcher对象添加到订阅者列表中),在setter函数中通知订阅者更新视图。
2.模板编译:在编译阶段,Vue会解析模板中的指令,插值表达式等,生成可执行的渲染函数。渲染函数会建立起数据属性和视图之间的依赖关系,即将数据属性与侦听器(Watcher)关联起来
3.Watcher:Watcher是Vue中的观察者对象,用于监听数据的变化并更新视图。当模板中的数据发生变化时,Watcher会接收到通知,触发更新视图的操作。
4.视图更新:当数据放生变化时,相应的setter方法会被调用,从而通知Vue数据发生了变化,找到与该数据相关的Watcher对象,并执行Wathcer的更新方法,将更新结果渲染到视图上,实现了数据的双向绑定效果

组件的重新渲染

在Vue2中组件的重新渲染主要发生在组件的updated生命周期钩子函数中,updated生命周期钩子函数会在组件的数据发生变化,并且虚拟DOM重新徐渲染之后执行

组件重新渲染的流程

当组件的数据发生变化或父组件强制更新时。Vue2会重新渲染组件
步骤:
1.更新数据:组件的数据发生变化时,Vue会通知组件进行重新渲染
2.执行渲染函数:Vue会执行组件的渲染函数,生成新的虚拟DOM
3.比较差异:Vue会通过虚拟DOM的diff算法比较新旧虚拟DOM的差异,找出需要更新的部分
4.更新视图:Vue会更新真实DOM,只更新发生变化的部分,而不是重新渲染整个组件

Vue2是如何劫持data对象中的各种数据类型的

在Vue 2中,对data对象中的各种数据类型(包括对象、数组、基本数据类型等)的劫持是通过递归遍历对象属性并使用Object.defineProperty()方法实现的。具体来说,Vue对不同数据类型的劫持方式如下:
1. 对象(Object): 对于对象中的属性,Vue会递归遍历对象的每个属性,并使用Object.defineProperty()方法为每个属性定义getter和setter,以实现对对象属性的劫持。当对象属性被访问或修改时,Vue能够捕获这些操作并触发更新。
2. 数组(Array): 对于数组,Vue会重写数组的原型方法(如push、pop、shift等),以实现对数组的变化进行监听和响应。通过重写数组的原型方法,Vue能够实现对数组的劫持,确保对数组的操作能够触发更新。 Vue会将数组的原型方法进行重写,将这些方法指向Vue定义的新方法,这些新方法会在执行时触发Vue的响应式更新机制。
Vue2并没有劫持数组的下标,因此当通过下标修改数组时,无法触发视图的重新渲染
3. 基本数据类型(Number、String、Boolean等): 对于基本数据类型,Vue会将其包装成响应式对象,然后再进行劫持。Vue会为基本数据类型创建一个包装对象,并使用Object.defineProperty()方法为包装对象定义getter和setter,以实现对基本数据类型的劫持。

通过以上方式,Vue能够实现对data对象中各种数据类型的劫持,实现数据的响应式更新和视图的自动更新。这种劫持机制使得Vue能够实现数据驱动视图的特性,让开发者能够更便捷地处理数据和视图之间的关系。

Vue2中,对data中某个对象的原有属性值进行修改,会不会触发渲染?(会,因为数据劫持
Vue2中,对data中某个对象的新增属性值进行修改,会不会触发渲染 (不会,因为数据劫持发生在vue初始化阶段,用 s e t ,因为 set,因为 set,因为set相当于新一轮的数据劫持)

这是因为Vue在实例化时会对data对象进行响应式处理,只有已经存在于data中的属性才会被Vue的响应式系统追踪和监听变化。
当你向data中的对象新增属性时,这个新增的属性并不会被Vue的响应式系统捕获到,因此对新增属性的修改不会触发视图的重新渲染。如果想要让新增的属性也能触发视图更新,可以使用Vue.set()方法或者this.$set()方法来添加响应式属性,这样新增的属性就会被Vue监听到,并能触发视图的重新渲染。

给Vue2添加新的响应式属性的方法
//this.obj是要添加新属性的对象,'newProperty'是新属性的名称,value是新属性的值。
Vue.set(obj, 'newProperty', value);
this.$set(this.obj, 'newProperty', value);

使用Vue.set()或this.$set()方法添加新的响应式属性后,这个新属性就会被Vue监听到,能够触发视图的重新渲染。这样就可以动态地向Vue实例中的对象添加新的响应式属性,实现数据的动态更新和视图的同步显示。

Vue2中,对data中某个数组,用下标的表示修改值,会不会触发渲染?(不会)

Vue无法直接捕获这个操作,因为Vue只能劫持对象属性的访问和修改,而不是数组的下标操作。因此,Vue无法知道数组元素的变化,也就无法触发视图的重新渲染。
为了解决这个问题,Vue提供了Vue.set()方法或this.$set()方法来确保对数组的修改能够被Vue监听到。这两个方法会向数组中添加一个新的属性并触发视图更新,从而让Vue能够检测到数组的变化。

Vue2中,对data中某个数组进行push、pop会不会触发渲染?(会,vue的初始化阶段对数组方法进行重写,重写逻辑和$set差不多,新做了一次数据劫持)

在Vue 2中,对data中某个数组进行push、pop等操作会触发视图的重新渲染。这是因为Vue 2重写了数组的push、pop等方法,并在这些方法内部添加了更新视图的逻辑。当调用这些数组方法时,Vue能够捕获到数组的变化,并触发视图的重新渲染,确保视图与数据的同步更新。

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

当data直接是一个对象时,多个组件会共同引用同一个数据对象,当其中一个组件修改了数据,其他组件也会受到影响,造成数据混乱。通过将data定义为一个函数,每次组件创建实例时,都会调用该函数返回一个新的数据对象,从而避免了数据共享的问题

computed和watch的区别,使用场景,举例

使用目的不同:computed是根据其所依赖的属性的值计算一个新属性的值,并将其作为响应式属性暴露给用户,适用于简单的计算逻辑;而侦听器则用于在某些数据变化时候执行异步或开销较大的操作
触发时机不同:计算属性会在其所依赖的属性发生变化时自动更新,而侦听器可以设置要观察的属性,只有当这些属性发生变化时才触发回调

使用场景举例:
场景一 - 使用computed: 假设在一个电子商务网站的项目中,有一个商品列表页面,每个商品有价格和折扣信息,需要计算出每个商品的实际价格(考虑折扣)并展示在页面上。这时可以使用computed属性来计算每个商品的实际价格
场景二 - 使用watch: 假设在一个社交媒体应用的项目中,用户有一个个人资料页面,需要监控用户个人资料的变化,并在变化时发送请求更新用户信息。这时可以使用watch属性来监听用户个人资料的变化

diff算法

虚拟DOM是真实DOM的js对象
在这里插入图片描述

Vue2 Diff算法总结(图文结合)
点击前往
Vuediff算法视频:点击前往

key值,为什么不推荐用index去当成key使用(基本上这一点要结合diff算法去回答)

v-for没有key值会发生什么

1.在vue虚拟DOM的对比算法中,无法识别两次渲染的具体变化,只能对整个列表进行重新渲染,从而导致性能下降
2.当数组的顺序发生变化时,vue会认为这是两组不同的元素,从而销毁原来的元素,创建一个新元素,可能导致浏览器的重绘与回流,影响渲染性能
3.当数组中有相同的值时,无法区分,可能会引起一起隐藏问题,如选中状态,切换状态等

key的工作原理

1.当Vue更新渲染真实DOM时,他会对新旧节点进行比较,找出他们之间的差异
2.如果两个节点具有相同的key值,则vue会认为它是相同的节点,会尝试复用已存在的真实DOM节点
3.如果节点具有不同的key值,Vue会视为不同的节点,并进行适当的更新,移动或删除操作

为什么不推荐用index去当成key使用
  1. 节点身份识别问题: 使用index作为key值时,Vue在进行节点比较时无法准确识别节点的身份。因为index是根据节点在数组中的位置生成的,当数组发生变化时,原本的index也会发生变化,导致Vue无法正确识别节点的身份,从而可能出现错误的更新或重渲染。
  2. 节点重用问题: 使用index作为key值时,Vue无法准确判断哪些节点是新增的、哪些节点是更新的、哪些节点是删除的,从而无法高效地重用节点。这可能导致不必要的DOM操作,影响性能。

http://www.ppmy.cn/devtools/16744.html

相关文章

Elasticsearch索引数据的路由规则与自定义路由分发

Elasticsearch通过路由规则将数据高效地分布到各个分片中,实现数据均衡、查询优化及故障恢复。本文将深入探讨索引数据路由的原理,并通过示例展示如何使用自定义路由策略分发数据。 索引数据路由原理 默认路由规则 默认情况下,Elasticsear…

区块链技术与应用学习笔记(12-13节)——北大肖臻课程

目录 12.BTC-匿名性 一、什么是匿名? 1,有可能破坏比特币匿名性的两个方面 2,如何提高匿名性 一个比特币用户能采用什么样的方法尽量提高个人的匿名性? 分解: 1、网络层怎么提高匿名性? 2、应用层怎么提高匿名性? 零知…

致力于为企业提升媒体宣传的一种新策略-软文发稿和投放

随着新媒体时代的快速发展,媒体宣发的方式也在不断迭代,其中,“软文发稿”成为了许多企业非常看重的一种媒体宣发方式。那么,什么是“软文发稿”呢?这是一种通过撰写有新闻属性的广告文章,将企业的品牌、产…

SpringCloud使用Nginx代理、Gateway网关以后如何获取用户的真实ip

前言 本文转载自: www.microblog.store,且已获得授权. 一、需求背景 微服务架构使用了Nginx代理转发、并且使用了SpringCloud的Gateway统一控制所有请求,现在有个需求: 做一个日子记录切面,需要记录用户请求的ip地址。 在上述双重背景下…

K8S Service 常见问题

Service 问题排查 为了演示需要部署以下服务。 apiVersion: apps/v1 kind: Deployment metadata:name: busyboxnamespace: appslabels:app: busybox spec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busybo…

网络安全之弱口令与命令爆破(上篇)(技术进阶)

目录 一,什么是弱口令? 二,为什么会产生弱口令呢? 三,字典的生成 四,使用Burpsuite工具弱口令爆破 总结 一,什么是弱口令? 弱口令就是容易被人们所能猜到的密码呗,…

先进制造aps专题三 为什么java语言不适合作为aps算法的开发语言

为什么java语言不适合作为aps算法的开发语言 主要两个原因 1 java的list在特定位置插入,其实是重新生成一个新list,而不像c就是指针操作 2 数据量大,运行时间长,会跑崩 所以商业aps产品,都是清一色的用c写aps算法 先进制造…

centos7.9下安装SVN服务

一、安装subversion yum install -y subversion #安装svn mkdir -p /data/svnrepos/java #自定义svn仓库位置/data/svnrepos,自定义一个项目叫svn(这里新建目录) svnadmin create /data/svnrepos/java #创建一…