vue2生命周期(vue2生命周期面试题)

vue2生命周期(vue2生命周期面试题)Vue2 0 兼容 ie 哪个版本 不支持 ie8 部分兼容 ie9 完全兼容 ie10 因为 vue 的响应式原理是基于 es5 的 这个方法不支持 ie8 及以下 解释下 MVVM 模式 MVVM 是 Model View ViewModel 的缩写 model 数据层 处理业务逻辑和数据 view 视图层 UI 视图 负责数据的展示 viewModel 负责监听 model 中数据的改变并控制视图的更新 处理用户操作 Vue 的优点 缺点 优点 数据驱动



Vue2.0 兼容 ie 哪个版本?

不支持 ie8,部分兼容 ie9,完全兼容 ie10
因为 vue 的响应式原理是基于 es5 的 这个方法不支持 ie8 及以下

解释下 MVVM 模式?

MVVM 是 Model-View-ViewModel 的缩写

model 数据层:处理业务逻辑和数据
view 视图层:UI 视图,负责数据的展示
viewModel 负责监听 model 中数据的改变并控制视图的更新,处理用户操作

Vue 的优点?缺点?

优点:

  • 数据驱动 (自动计算属性和追踪依赖的表达式)
  • 组件化 (可以复用,解耦的组件来构建页面)
  • 轻量(代码量小,不依赖其他库,大小只有几十 kb)
  • 渐进式
  • 虚拟 DOM
  • 单页面路由
  • 数据与视图分离

缺点:

  • 单页面不利于 seo
  • 不支持 ie8 及以下
  • 首屏加载时间长

Vue 的两个核心?

  • 数据驱动
  • 组件化

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

解释:
当组件中的 使用对象时,因为对象是引用类型,所有组件实例的 都会指向同一个内存地址。在其中一个组件中修改数据,其他组件的数据也会发生变化
而使用返回对象的函数,每次返回一个新的对象,函数返回的对象内存地址并不相同。则不会存在这个问题

下面用代码举例说明:
我们模仿一个组件构造函数,定义 属性,采用对象的形式


创建两个组件实例:


修改组件属性的值,中的值也会发生变化


通过代码我们能看出: 组件就是一个 实例,通过构造函数来创建。每个实例都会继承原型上的方法属性。就是 原型上的一个属性,当是对象的时候,每个实例的 就会指向同一个内存地址,每个组件之间的数据就会相互影响

如果我们采用函数的形式,则不会出现这种问题(函数返回的对象内存地址并不相同)


修改组件属性的值,中的值不会受影响


动态给 data 添加一个属性会发生什么?怎么解决?

现象: 数据会更新,但视图不会更新
原因: 动态添加的属性没有通过 设置成响应式数据

data 中哪些对象操作无法监听?为什么?怎么解决?

  • 对象属性的添加、删除

原因: 因为 的响应式原理是通过 来实现的。只能劫持到对属性的获取或修改,无法追踪新增和删除属性。

解决方法:

  • 属性添加可以使用

  • 属性删除可以使用

data 中哪些数组操作无法监听?为什么?怎么解决?

  • 利用索引直接设置一个数组项时:
  • 直接修改数组的长度:

原因:Vue 没有对数组的属性进行劫持

解决办法:

怎么重置数据?

  1. 重置整个 data

  1. 重置单个对象数据(比如重置 form 表单数据)

不需要响应式的数据应该怎么处理?

  1. 使用

  1. 在 data 外定义

watch 和 computed 的区别?

  • watch 适合一个数据影响多个数据。当需要在数据变化时:执行异步操作或开销较大的操作时(搜索)
  • computed 适合一个数据受多个数据影响。是基于他的响应式依赖进行缓存的,只有相关响应式依赖属性发生变化才会重新计算(计算价格)

watch 怎么初始化的时候被立即调用?

在选项参数中添加 将立即以表达式的当前值触发回调


watch 怎么深度监听对象变化?

在选项参数中添加


computed 中的属性名和 data 中的属性名可以相同么?

不能同名,因为 computed 属性、data 属性、props 属性都会被挂载 vm 实例上


data 属性名和 methods 的属性名可以相同么?

不能同名,有限制,会报错



列举常用的指令有哪些?

、、、、、、、、、、

列举表单修饰符和事件修饰符

事件修饰符:

  • 阻止事件冒泡
  • 阻止默认事件(a 标签、浏览器鼠标事件、form 表单提交)
  • 事件默认是冒泡,capture 作用是捕获
  • 只有绑定点击事件的本身才会触发事件
  • 监听一个自定义事件,只会触发一次,一旦触发后,监听器就会被移除
  • 加在自定义组件的事件上,保证事件能执行(解决给组件绑定自定义事件无效)
  • 父组件传值加上这个修饰符,子组件可直接修改传过来的值

表单修饰符:

  • 改变输入框的值时 value 不会改变,当失去焦点的时候。v-model 绑定的值 value 才会改变
  • 去掉 v-model 绑定的值首尾空格
  • 将值转换成数字(先输入字符串和先输入数字,是两种情况,先输入数字的话,只取前面数字部分,先输入字母的话,number 修饰符无效)

v-if 和 v-show 的区别?

  • 相同点:都可以控制元素的显示和隐藏

  • 不同点

    • 是通过创建和销毁元素来达到显示隐藏
    • 是通过的属性来达到显示隐藏
  • 性能消耗
    有更高的切换消耗,有更高的初始化渲染消耗,频繁显示隐藏用

v-if 和 v-for 的优先级是什么?

两者作用于同一标签时, 的优先级比 高。
尽量不要把 和 使用同一个元素上,会带来性能方面的浪费(每次渲染都会先循环再判断)。可以使用 进行过滤

v-for 遍历,是按照什么顺序遍历的?如果保证顺序?

按照 的顺序遍历
转成数组保证顺序

v-model 的实现原理?

v-model 是分别利用了 v-bind 绑定 value 的值,v-on 绑定 input 事件,通过$event 进行赋值


v-once 有什么用?

只渲染元素和组件一次。下次渲染,会被视为静态内容并跳过

谈谈你对 keep-alive 的了解?

含义:是一个抽象组件,他自身不会渲染成一个 DOM 元素,也不会出现在父子组件中
作用:使用 包裹动态组件时,会缓存不活动的组件实例,而不是销毁他们
属性介绍:、、

  • include:缓存白名单,包含的组件会被缓存
  • exclude:缓存黑名单,包含的组件不会被缓存
  • max:最多可以缓存多少组件实例,一旦达到这个数字,在新实例被创建前,已缓存组件中最久没有被访问的实例会被销毁掉

的基本用法:


使用 和 :


keep-alive 的原理?

keep-alive 是一个组件,组件有三个属性:、、
在其内部维护了一个 key 数组和一个缓存对象:数组记录目前缓存的组件值,如果组件没有指定值,会自动生成一个唯一的值。缓存对象 ,会以值为键,vnode 为值,用于缓存组件对应的虚拟 DOM
在中会监听和属性,进行组件的缓存处理,如果发生变化会动态的添加和删除属性
在的渲染函数中,会判断当前渲染的是否有对应的缓存,如果有会从缓存中读取对应的组件实例,如果没有就会把他缓存
当缓存的数量超过设置的数值时,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉

为什么 keep-alive,不会渲染成真正的 DOM 节点

底层中有一个 属性,会根据该属性决定是否忽略某个组件
在 中设置了 表示该组件为抽象组件,不会被渲染 DOM,跳过该组件实例

跟 keep-alive 相关的生命周期有哪些?

  • 组件激活时调用
  • 组件停用时调用

以上钩子服务端渲染期间不被调用

组件通信都有什么方式?

  • 、、

父子组件通信?

props 和 $emit

  • 父传子:父组件在子组件标签上绑定数据,子组件设置 props 来接收
  • 子传父:子组件通过 触发自定义事件,第二个参数为传递的数据,父组件绑定自定义事件来监听传过来的数据

prop 验证的 type 类型有哪几种?

、 、、 、 、 、 、

子组件怎么直接修改父组件传过来的数据?

父组件在传值的时候加上,子组件在自定义事件加上


依赖注入怎么使用?解决了什么问题?

provide 和 inject

作用:解决了嵌套组件的通信问题

使用:

  • 在祖先组件定义 provide 属性,返回向下传递的值
  • 在后代组件中通过 inject 接收传过来的值

注意:传递的值需要是对象才能实现响应式,如果是基本类型就无法实现响应式



Vue 生命周期有哪些?

  • Vue 实例创建前:数据初始化还没有完成,像 data、props 等属性还无法访问
  • Vue 实例创建后:完成了数据观测(data、props、computed 等),属性和方法(method)的运算。完成了数据代理
  • 实例挂载前:生成了 Watcher,调用 render 函数,生成虚拟 DOM,但是还没转换成真实 DOM
  • 实例挂载后:真实 DOM 挂载完毕
  • 数据更新前调用:新的虚拟 DOM 生成,但是还没有对比打补丁
  • 数据更新后调用:新旧虚拟 DOM 对比打补丁,进行真实 DOM 的更新
  • 实例销毁前调用:此时实例仍然完全可用,可以访问数据
  • 实例销毁之后调用:此时实例的所有东西都会解绑,所有的事件监听器都会被移除,所有的子实例也会被销毁

父子组件 渲染 生命周期顺序

父 → 父 → 父 → 子 → 子 → 子 → 子→ 父

父子组件 更新 生命周期顺序

父 → 子 → 子 → 父

父子组件 销毁 生命周期顺序

父 → 子 → 子 → 父

在 created 和 mounted,这两个生命周期中请求数据有什么区别?

在中,页面视图未出现,如果请求信息过多,会阻塞渲染,页面会长时间处于白屏状态
在中,页面已经渲染完成,则不会有这种情况

第一次页面加载会触发哪几个钩子?

beforeCreate、 created、 beforeMount、 mounted

DOM 渲染是在那个生命周期完成的?

在 mounted 生命周期

$nextTick 有什么作用?

将中的回调延迟到下次 更新循环结束之后执行。
采用的是异步更新策略,同一事件循环内,多次修改,会统一进行一次视图更新,所以数据一更新,视图还未更新,所以拿到的还是上一次的旧数据

$nextTick 的实现原理?

主要使用异步队列来控制
数据响应过程:数据更新 → 通知 Watcher → 更新 DOM,其中的数据更新 DOM 是个微任务
就是将回调函数添加到了更新 的 队列中,确保代码在 更新后执行

根据浏览器的渲染机制,渲染线程是在微任务执行完成之后执行的,渲染线程还没运行,怎么获取到 dom 的呢?

渲染线程只是把 DOM 树渲染成 UI 而已。
Vue 更新 DOM 之后,在 DOM 树里,新的 DOM 已经存在,就可以拿到新的 DOM 了

key 的作用?

给元素添加了标识,优化复用对比策略,提高渲染性能
Vue 为了高效渲染元素,默认会复用已有元素而不是重新渲染。为元素添加 key,当列表数据发生变化,会根据 key 找到已渲染的元素进行复用,对顺序不匹配的元素进行位置的调整
如果不使用 key,默认采用“就地更新”策略,如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素

为什么 style 上加 scoped 能实现样式私有化?

通过 结构以及 样式上,加上唯一的标记,保证唯一,达到样式私有化,不污染全局的作用

dom 上的 data-v-xxxxx 是做什么的?(和上面问题一样,只是问法不一样)

这是在 中,写 时使用 标记产生的,保证了各个组件中的 不相互影响,给每个组件都做了唯一标记

深度选择器

  • >>>

只能作用于 css,使用了预处理语言的 css 不生效


  • /deep/ (只能在 vue2 中使用)

只能作用于 less 或者 sass


  • ::v-deep (目前 vue2 和 vue3 都可使用)

只能作用于 less 或者 sass


  • :v-deep() (vue3 中使用)

怎么动态绑定 class?

  • 对象语法

  • 数组语法(三元表达式)

  • 对象和计算属性直接返回


配置 proxy 为什么能解决跨域问题?

跨域问题是存在于浏览器端,服务器与服务器之间的请求不存在跨域问题
配置 proxy 相当于在本地创建了虚拟服务器,使用虚拟服务器去代理请求

Vue 数据响应式原理?

采用数据劫持结合发布订阅的方式,通过 劫持属性,在数据变化时,发布消息给订阅者,触发相应的监听回调

在 实例初始化的时候,会对数据进行递归遍历,通过 对数据属性进行代理。
这样做的作用是:

  1. 当渲染视图的时候,会先编译 中的 模板,解析模板指令,将模板中的变量替换成数据,这样就会触发 getter 进行依赖收集,依赖收集是指将订阅者 存放到订阅器 里面
  2. 当数据发生变化时,会触发 setter,setter 会通知订阅器 ,订阅器会循环遍历之前收集到的,告诉他们自己的值改变了,需要重新渲染视图,这时候 就会调用自身的 来更新视图

为什么 Vue 中 data 更新后,不能立即获取到 DOM?

受异步更新策略影响,Vue 在修改数据后,视图不会立即更新,而是等同一事件循环的所有数据变更完成之后,在统一进行视图更新

讲一下 Vue 实例挂载过程?

说说 Vue 模板的编译过程?

Vue 模板编译(Vue template compilation)是指将 template 模板转换为可执行的 JavaScript 代码的过程
Vue 模板编译分为以下几个阶段:

  1. 解析代码(Parsing):这个阶段主要是解析器(Parser)解析模板中的 HTML 标签、文本内容、指令等,生成抽象语法树(AST Tree)
  2. 优化阶段:遍历 AST 树,找出其中的静态节点,打上标记,(作用是:diff 算法会直接跳过静态节点,从而减少了比较的过程,优化了 patch(对比打补丁)的性能)
  3. 生成代码(Code Generation):将 AST Tree 转化为可执行的 JavaScript 代码。代码生成器遍历 AST Tree 生成对应的渲染字符串和渲染函数,这个渲染函数主要是在实例挂载和 DOM 更新时被调用
  4. 运行时(RunTime):当 Vue 实例被创建并挂载到 DOM 上时,渲染函数会被调用,生成对应 DOM 结构。当数据发生变化时,渲染函数会重新执行,更新 DOM,在此过程中,Vue 会使用虚拟 DOM 技术来减少实际的 DOM 操作次数,提高性能

watch、methods 中的属性和方法,可以使用箭头函数定义么?

不可以,this 会是 undefined
所有的生命周期钩子,内置方法,自动绑定 this 上下文到实例中,因此可以访问数据,对属性和方法的运算。
箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例

组件和插件的区别?

1. 编写方式的不同

  • 组件编写:最常见的就是 vue 单文件的这种格式,每个.vue 文件都可以看成是一个组件
  • 插件编写:会暴露一个 install 方法,这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象

2. 注册方式的不同

  • 组件注册:分为全局注册和局部注册,通过
  • 插件注册:通过

3. 使用场景

  • 组件 Component:解耦页面,拆分和封装页面公共的业务模块
  • 插件 Plugin:扩展 Vue 的功能

谈谈你对自定义指令的理解?

指令本质是装饰器,是 Vue 对 HTML 元素的扩展,增加自定义功能

自定义指令五个生命周期:

  • bind 只调用一次,指定一个绑定到元素时调用
  • inserted 被绑定元素插入父节点时调用
  • update 被绑定元素所在的模块更新时调用
  • componentUpdated 被绑定元素所在模块完成一次更新时调用
  • unbind 只调用一次,指令与元素解绑时调用

混入(mixins)

  1. 局部混入

  1. 全局混入
    2.1. 新建 mixin.js

    
    

    2.2 在 main.js 中引用

    
    

混入(mixins)的作用?有什么需要注意的地方?

作用:用来抽离公共的数据和方法,提高代码复用性

需要注意如下:

  • 同名函数合并为数组,都会执行,先执行 mixin 中的同名函数
  • 同名数组会进行替换,组件内的数据会将 mixin 的进行覆盖
  • 应该尽量只在页面的父组件(包含所有页面的组件)中使用混合。尽量不通过使用全局设置,通过这种方式,会为所有组件导入它,混入的方法会被执行多次

mixin 可以定义公用的变量和方法,mixin 中的数据和方法是独立的,每个组件中的 mixin 实例都是不一样的,不存在相互影响

属性书写顺序


Vue 和 jquery 的区别?

  • jquery 是直接操作 DOM。Vue 数据和视图分离,不直接操作 DOM,只需要操作数据即可
  • jquery 操作的是真实 DOM,操作行为也很频繁。Vue 利用虚拟 DOM 技术,提高了更新 DOM 的性能
  • Vue 集成的一些库,比如 Vuex、Vue-Router 等,可以提高开发效率

assets 和 static 的区别?

相同点:两者都存放静态资源文件的
不同点:assets 存放的文件,在打包的时候,会进行打包压缩体积。
statis 存放的文件不会进行打包压缩,而是存入指定的目录,因为跳过了这一流程,在打包时会提高一定效率,但因此也会占用服务器更大空间

name 选项有什么作用?

  • 递归组件。调用自身时使用
  • 和 时使用
  • 中, 和 使用

怎么强制刷新组件?

  • this.$forceUpdate()
  • 组件加上 key,变化 key 的值

组件在什么时候会被销毁

  • 没有使用,进行路由切换

Vue 组件里写的原生 addEventListener 事件,需要手动销毁么?为什么?需要注意什么?

需要在 中销毁,不然会造成多次绑定和内存泄露
注意事项:

  • 执行函数必须使用外部函数

    
    
  • 执行函数不能是匿名函数

    
    
  • 执行函数不能改变 this 指向

    
    
  • addEventListener 和 removeEventListener 第三个参数必须一致

    
    

在 Vue 事件中是如何使用 event 对象的?

事件参数中传入 对象

在 Vue 事件中传入$event,使用 $event.target 和 $event.currentTarget 有什么区别?

  • $event.currentTarget 指向事件所绑定的元素
  • $event.target 指向事件触发的元素

什么是虚拟 DOM?

虚拟 是对真实 的抽象,用 对象作为一个容器,用对象的属性来描述节点,最终通过一系列操作来映射到真实 上

为什么需要虚拟 DOM?

操作真实 是很慢的,哪怕一个最简单的 也会包含很多属性

操作 的代价是昂贵的,频繁操作还是会出现页面卡顿,影响用户的体验

举例
比如用 ,操作的都是真实
当在一次操作时,需要更新 10 个 节点,浏览器没那么智能,收到第一个更新 请求后,会马上执行流程,最终会执行 10 次
而通过 ,同样更新 10 个 节点,虚拟 不会立即操作 ,而是通过 算法比较需要更新的地方,将这 10 次更新的内容保存到本地的一个 对象中,最终将这个 对象一次性更新到 树上,避免了大量的无用计算





编程小号
上一篇 2025-01-25 08:21
下一篇 2025-01-26 13:30

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/15722.html