Vue高频面试题

发布时间 2024-01-05 00:49:25作者: 前端自信逐梦者

1. 谈谈你对 Vue 的理解?

Vue 是一个渐进式的 js 框架,专注于构建用户界面。
Vue 的核心思想是数据驱动和组件化,通过将页面拆分为多个独立的组件,可以更好的管理到吗,
提高代码的复用性和可维护性。
Vue 的优势在于:简单易用,灵活性高,性能卓越和拓展性强。
Vue 的模板语法易于理解和学习,快速搭建 web 应用程序,同事 Vue 还提供了生命周期钩子和自定义函数等功能,可以实现较为复杂的业务场景,另外 Vue 还有强大的生态,提供了 Vuex,Vue router 等,进一步扩展 Vue 的功能。
Vue 的响应式数据绑定是 Vue 最核心的特性之一,通过数据劫持和监听,实现数据的双向绑定,即数据变化可以引起视图更新,同时视图的变化也会反映在数据上。

2. Vue 的 nextTick()原理

官网定义:等待下一次 DOM 更新刷新的工具方法。
在 Vue 中,有一个异步更新策略,它的原理是基于浏览器的异步任务队列,即当数据发生变化的时候,Vue 并不会立即去更新 DOM,而是开启一个异步任务队列,把 DOM 更新的操作保存在队列中,等待下一次事件循环时执行。
Vue.nextTick()则是将一个回调函数推入到异步任务队列中,等待 DOM 更新完成后执行。

2.1 具体实现方式

注意: 由于不同浏览器支持的异步任务方法不同,Vue 会根据浏览器的支持情况选择合适的异步任务方法(微任务到宏任务的降级处理)。

Promise 的 then -> MutationObserver 的回调函数 -> setImmediate -> setTimeout

  1. 使用原生 setTimeout 方法:在 Vue2 中,如果浏览器支持 Promise,则优先使用 Promise,如果不支持,则会使用 setTimeout 模拟异步操作。
  2. 使用 MutationObserver:如果浏览器支持 MutationObserver,vue 会使用 MutationObserver 监听 DOM 更新,并在 DOM 更新完成后执行函数。

    MutationObserver 是 HTML5 新增的属性,用于监听 DOM 修改事件,属于微任务

  3. 使用 setImmediate 方法: 在 IE 中,setImmediate 可以用来延迟执行异步任务,在 Vue2 中,如果浏览器支持 setImmediate,则会有限使用 setImmediate,否则使用 setTimeout。

3. 谈谈你对 Vuex 的理解

3.1 定义

Vuex 是一个专门为 vue.js 开发的一个状态管理库,提供了一个集中式的状态管理机制,管理多个组件的共享状态。

3.2 必要性

我们通常希望以一种单向数据流的方式去管理应用,即 state-->view-->actions 这种单向循环的方式,但是当个组件共享一个状态的时候,比如多个视图需要依赖同一状态,挥着来自不同视图的行为需要变更某一个状态,这就容易破坏这个单向数据流,这就需要将多个组件共享的状态提取出来,以一种全局单例管理模式去管理。

3.3 五大概念以及使用

import { mapState, mapGetters, mapActions, mapMutations } from 'vuex';
export default {
  data() {
    return {};
  },
  computed: {
    ...mapState(['count', 'num']),
    ...mapGetters(['age']),
  },
  methods: {},
};
3.3.1. state

提供了一个公共数据源,存放组件的共享数据。

使用方法

  1. this.$store.state.变量名
  2. 使用辅助函数...mapState(['count','name'])
3.3.2. mutations

mutations 是一个对象,里面存放了修改 state 中数据的方法,想要修改 state 中的数据,只能通过 mutations,且 mutations 必须是同步的。
mutations 中方法的参数: 第一个是 state 属性,第二个的参数是传递参数,且只能传递一个参数,若想传递多个,可以传递一个对象。

使用方法

  1. this.$store.commit('addCount', 2)
  2. 使用辅助函数...mapMutations(['addCount'])
3.3.3. actions

mutations 中的方法都是同步,要想处理异步的逻辑,可以写在 actions 中,
actions 中的方法提交的是 mutation
actions 中方法的参数: 第一个是具有和 store 实例相同属性和方法的 context 对象,第二个参数是传递参数,用来传值

使用方法

  1. this.$store.dispatch('setAsyncCount', 2)
  2. 使用辅助函数...mapActions(['setAsyncCount'])
3.3.4. getters

有时候需要派生出 state 中的一些状态,这些状态又是依赖于 state 的。
getters 中方法的参数: 接收 state 参数

使用方法

  1. this.$store.getters.getDoubleCount
  2. 使用辅助函数...mapGetters(['getDoubleCount'])
3.3.5. module

由于 vuex 使用的是全局单一管理模式,所有的状态都会放在一个 state 中,这就会造成 state 臃肿,当 state 中存储的数据越来越大,就会变得难以维护。

// moduleA和moduleB都是一个
const moduleA = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB,
  },
})
/*
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
*/

3.4 Vuex 的优缺点?

优点:

  • 实现了多个组件的状态共享
  • 提供了插件机制,可以对 vuex 的功能进行扩展

缺点:

  • 无法持久化数据
  • 使用了模块化,在访问 state 时,需要带上模块名,如果模块多层嵌套的话,代码会显得冗余,容易出错
  • 对 TS 的支持不友好
拓展:命名空间

如果在模块中设置了 namespaced: true, 在使用辅助函数的时候一定要传入模块名。

...mapState('moduleA', ['count', 'name'])
...mapMutations('moduleA', ['addCount'])

4. vue router 路由管理