记录_面试题_VUE篇

164 阅读7分钟

1. vue生命周期

  • 第一阶段(创建阶段):beforeCreate、created
  • 第二阶段(挂载阶段):beforeMount、mounted
  • 第三阶段(更新阶段):beforeUpdate、updated
  • 第四阶段(卸载阶段): beforeUnmount、unmounted

created(创建后):

数据对象 data 已存在,可以调用 methods 中的方法,操作 data 中的数据,但 dom 未生成

mounted(挂载后):

vue 实例挂载完成,用户已经可以看到渲染好的页面了,在这个阶段可以对dom进行操作

2. vue的双向绑定原理是什么?

Vue2

1、原理:通过数据劫持和发布订阅模式来实现。通过Object.defineProperty()来劫持各个属性的setter和getter,并在geeter和setter中添加响应的依赖和观察者。当数据发生变化时,setter会通知相关的观察者更新视图。当组件被销毁时,会清除该组件的所有依赖和观察者。

2、优点:

  • 向后兼容性:兼容老版本
  • 数据变化能够自动更新视图,视图变化也能够自动更新数据

3、缺点:

  • 对对象劫持,需要对属性进行重写添加getter和setter,多层嵌套对象时,性能差
  • 对数组不采用defineProperty来劫持,单独处理,改写数组原有方法,对所有索引劫持造成性能浪费

Vue3

1、原理:使用ES6的proxy来实现响应式。通过reactive()函数将data对象转换为响应式对象,使用proxy对对象进行拦截。当读取对象的属性时,在get方法中收集依赖WeakMap,每个reactive对象对应一个Map,用于存储该对象的所有依赖;当属性发生变化时,会触发set方法,通过找到当前对象属性所存储的依赖集Set,触发更新。

2、优点:

  • 解决了vue2中Object.defineProperty的问题

3、缺点:

  • 向后兼容性差,不支持老版本浏览器
  • 不可变性和不可拓展性。Proxy创建的对象是不可变的。Obeject.freeze()或Obeject.seal()无法改变对象的不可变性和不可拓展性。

3. vue的组件间通信方式有哪些?

(1)props / emits :父组件通过 props传值给子组件,子组件通过 emits 通知父组件触发一个事件,并且可以传值给父组件。

(2)expose / ref :子组件可以通过 expose 暴露自身的方法和数据,父组件通过 ref 获取到子组件并调用其方法或访问数据。

(3)provide / injectprovide 是在父组件里使用的,可以往下传值,inject 是在后代组件里使用的,可以往上取值。

(4)Vuex / Pinia :主要解决 跨组件通信 的问题。

4. vue的nextTick作用?

  • 当调用 nextTick() 方法时,Vue 将回调函数放入一个队列中,等待下次 DOM 更新循环结束后执行。
  • Vue 的数据变化会触发重新渲染 DOM,这个过程是异步的,数据变化后并不会立即更新 DOM,而是等待下一个事件循环才会进行 DOM 更新。
  • 在所有同步任务执行完毕后,Vue 开始执行异步队列中的回调函数,此时 DOM 已经更新完成,确保在回调函数中获取到最新的 DOM

5. vue中的keep-alive是什么?它有什么作用?

它是Vue中的一个内置组件,用于缓存动态组件。当组件包裹在中时,组件的状态将被保留,包括它的实例、状态和DOM结构。这样可以避免在组件切换时重复创建和销毁组件,提高性能和用户体验。

6. computed 和 watch 的区别?

(1)computed 是计算一个新的属性,并将该属性挂载到 Vue 实例上,而 watch 是监听已经存在且已挂载到 Vue 实例上的数据,所以用 watch 同样可以监听 computed 计算属性的变化。

(2)computed 本质是一个惰性求值的观察者,具有缓存性,只有当依赖变化后,第一次访问 computed 属性,才会计算新的值。而 watch 则是当数据发生变化便会调用执行函数

(3)从使用场景上说,computed 适用一个数据被多个数据影响,而 watch 适用一个数据影响多个数据

7. v-show 和 v-if 的区别?

v-show: 本质就是通过设置 display 控制隐藏

v-if: 动态的向 DOM 树添加或者删除元素

应用场景: 都是控制元素隐藏和显示的指令,切换显示/隐藏频繁用v-show不频繁可以用 v-if

8. v-for和 v-if 的优先级?

vue2中 v-for 比 v-if 具有更高的优先级,所以每次渲染时都会先循环再判断,用在一起会特别消耗性能,一般把v-if放在外层并且包一层template,然后内部进行v-for循环

vue3中 v-if 比 v-for 具有更高的优先级,所以每次渲染时都会先判断再循环,只有在条件满足的情况下,才会执行v-for循环来渲染相应的 DOM 元素。这种改变使得在类似上述性能问题场景下,能够避免不必要的v-for循环操作,从而提高了性能。

9. router和route的区别?

route:是一个局部对象,包含了路由参数

router:是一个全局路由对象,包含了路由的跳转方法,钩子函数等

10. vue 常用的修饰符?

  • .prevent: 提交事件不再重载页面
  • .stop: 阻止单击事件冒泡
  • .self: 当事件发生在该元素本身而不是子元素的时候会触发

11. vue 中 key 值的作用?

(1)v - if 场景

Vue 为高效渲染常复用元素,使用v - if切换相同类型元素时会复用已有元素,比如input元素切换前后用户输入可能保留,不符合需求。此时设置key可唯一标识元素,使其不被复用,key在此的作用是明确标识独立元素。

(2)v - for 场景

v - for更新已渲染元素列表默认采用 “就地复用” 策略,数据项顺序改变时,Vue 不移动 DOM 元素匹配,而是复用现有元素。为列表项设置key值能让 Vue 跟踪元素身份,实现高效复用,此时key的作用在于高效更新渲染虚拟 DOM。

12. vue-router常用路由模式有哪些?

  • hash模式

    • url会带有 /#/
    • hash改变不会发起请求
    • 兼容性更好
  • history模式

    • url更美观
    • 需要配合后端,不然会出现跳转页面返回出现404问题

13. 父组件如何监听子组件生命周期?

  • vue2 使用 @hook:mounted
  • vue3 使用 @vue:mounted
  • 自定义事件,在子组件生命周期中去执行
<template>
  <h1>Home 页面</h1>
  <Text @vue:mounted="fn" />
</template>

<script setup>
import { onMounted, ref } from 'vue'
import Text from '../components/Text.vue'

const fn = () => {
  console.log('Text mounted')
}
</script>

14. Vue3中 ref 和 reactive 的区别?

  • refreactive 都是响应式数据的创建

  • 参数不同

    • ref可以传引用数据和基础数据
    • reactive只能传入引用数据
  • 使用不同

    • ref在js中需要.value
    • reactive可以直接访问
    • templete中用法一样

15. this指向

  • 普通函数 指向window(非严格模式下,严格模式下指向undefined

  • 函数 中的this,谁调用指向谁

  • 箭头函数本身没有this,继承外层函数,如果有外层函数,外层函数的 this 就是内部箭头函数的 this ,如果没有,就是 window(非严格模式下)

16. call、apply和bind的区别?

  • 都可以改变this的指向
  • call和apply都可以立即调用
  • bind会返回一个新函数,需要手动调用,它预先绑定了一个this的值

17. 箭头函数

  • 箭头函数是一种匿名函数,当函数体是单条语句可以省略{}和return
  • 箭头函数没有自己的this
  • 箭头函数没有原型
  • 不能够作为构造函数

18. 什么是跨域,怎么解决?

出于浏览器的同源策略限制,当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同就会跨域。

解决:

  • webpack本地代理:在vue.config.js中配置本地代理
module.exports = {  
  devServer: {  
    port: 8000,  
    proxy: {  
      "/api": {  
        target: "http://localhost:8080"  
      }  
    }  
  }  
}
  • CORS跨域资源共享:需要服务端设置响应头
  • nginx反向代理

19. 如何提高页面的加载性能?

  • 路由懒加载
  • 组件按需加载
  • 减少HTTP请求
  • 启用浏览器缓存
  • 图片转 base64 格式