vue2面试题-2025-1-21

目录

1 v-if 和 v-show 的区别

2 为何 v-for 中要用 key

3 描述 vue 组件生命周期(以及有父子组件,两者的生命周期)

4 组件间如何通讯(常见)

5 组件渲染和更新的过程

6 双向数据绑定 v-model 的实现原理

7 说一下对 MVVM 的理解

8 computed 有何特点?

9 为何组件 data 必须是一个函数?

10 ajax 请求应该放在哪个生命周期?

11 如何将父组件的所有 props 传递给子组件?

12 如何自己实现一个 vmodel ?

13 多组件有相同的逻辑,如何抽离?

14 何时需要使用异步组件?

15 何时需要使用 keepalive

16 何时需要使用 beforeDestroy ?

17 什么是作用域插槽?为何需要它

18 vuex 的 action 和 mutation 有何区别?

19 vue-router 路由模式有几种?

20 如何配置 vue-router 异步加载?

21 场景题:用虚拟 DOM 描述一个 html 结构

22 监听data变化的核心API

23 vue 如何监听 data 变化?

24 vue 如何监听数组变化?

25 描述响应式原理

26 diff 算法时间复杂度是多少

27 简述 diff 算法过程

28 vue 为何是异步渲染?$nextTick有何用?

29 vue-router 如何实现路由变化?

30 vue 性能优化


1 v-if 和 v-show 的区别

  • v-show 通过CSS display 控制显示与隐藏
  • v-if 是组件真正的渲染和销毁,而不是显示与隐藏
  • 频繁切换用 v-show,否则用v-if

2 为何 v-for 中要用 key

  • 必须是key,不能是index和random
  • diff算法中通过key和tag来判断,是否是sameNode
  • 减少渲染次数,提高渲染性能

3 描述 vue 组件生命周期(以及有父子组件,两者的生命周期)

单个组件生命周期:

  • 挂载过程
  • 更新过程
  • 销毁过程

父子组件生命周期:(index父组件,list子组件)

  • 创建阶段

        index beforeCreate

        index created

        index beforeMount

        list beforeCreate

        list created

        list beforeMount

        list mounted

        index mounted

  • 更新阶段

        index before update

        list before update

        list updated

        index updated

  • 销毁阶段

        index before destroy

        list before destroy

        list destroyed

        index destroyed

4 组件间如何通讯(常见)

  • 父子组件 props 和 this.$emit
  • 自定义事件 event.$on event.$off event.$emit
  • vuex

5 组件渲染和更新的过程

(图示)

vue原理的三大模块:响应式、模版编译、虚拟dom

  • 初次渲染
    • 对 data 进行响应式处理,监听 get set
    • 解析模板为 render 函数(这一步可能在开发环境打包时就已经完成,重要!!!)
    • 执行 render 函数,生成 vnode (1 这一步会触发 data getter ,收集依赖,重要!!!2 将该数据 “观察”起来 3 注意,不一定所有的 data 都会被观察,得看模板中是否用到了,如下图。)
    • 将 vnode 渲染到页面上
  • 页面更新
    • 修改“被观察的”数据,触发 data setter
    • 重新执行 render 函数,生成 newVnode
    • patch(vnode, newVnode)双向数据绑定 vmodel 的原理

6 双向数据绑定 v-model 的实现原理

  • input 元素的 value = this.name
  • 绑定 input 事件 this.name = $event.target.value
  • data 更新出发re-render

7 说一下对 MVVM 的理解

(图示)

         Vue 中的 MVVM 模式是指 Model、View 和 ViewModel 的分离与协作。Model 管理数据和业务逻辑,View 负责用户界面,ViewModel 通过 Vue 的响应式系统连接 Model 和 View,自动实现数据双向绑定和视图更新。开发者只需关注数据逻辑,Vue 会处理 DOM 操作,使开发更高效,代码更简洁。

8 computed 有何特点?

  • 缓存,data不变不会重新计算
  • 提高性能

9 为何组件 data 必须是一个函数?

        在 Vue 中,组件的 data 必须是一个函数,这是为了确保每个组件实例都有独立的数据作用域。函数形式的 data 会返回一个新的数据对象,当多个组件实例化时,每个实例都可以拥有自己的独立数据副本,避免数据相互污染。如果 data 是一个对象,则所有实例会共享同一个数据对象,导致状态被意外修改。这个设计主要是为了保证组件的复用性和稳定性。

        首先组件data必须是一个函数,最根本的原因在于我们定义的vue组件是一个class(类),每个地方去使用这个组件的时候,相当于这个类的一个实例化,确保每个组件实例都有独立的数据作用域,避免相互污染。

10 ajax 请求应该放在哪个生命周期?

  • mounted
  • js是单线程的,ajax异步获取数据
  • 放在mounted之前没有什么用,只会让逻辑更加混乱

11 如何将父组件的所有 props 传递给子组件?

  • $props
  • <User v-bind = "$props" />
  • 细节知识点,优先级不高

12 如何自己实现一个 vmodel ?

13 多组件有相同的逻辑,如何抽离?

  • mixin(缺点)

14 何时需要使用异步组件?

  • 加载大组件
  • 路由异步加载

15 何时需要使用 keepalive

  • 缓存组件,不需要重复渲染
  • 如多个静态 tab 页的切换
  • 优化性能

16 何时需要使用 beforeDestroy ?

  • 解绑自定义事件 event.$off
  • 清除定时器
  • 解绑自定义的DOM事件,如 window scroll等

17 什么是作用域插槽?为何需要它

18 vuex 的 action 和 mutation 有何区别?

  • action中处理异步,mutation不可以
  • mutation做原子操作
  • action可以整合多个mutation

19 vue-router 路由模式有几种?

  • hash(默认)
  • h5 history(需要服务端支持)

20 如何配置 vue-router 异步加载?

21 场景题:用虚拟 DOM 描述一个 html 结构

<div id="div1" class="container">
    <p>vdom</p>
    <ul style="font-size: 20px">
        <li>a</li>
    </ul>
</div>

{
    tag: 'div',
    props: {
        className: 'container',
        id: 'div1'
    }
    children: [
        {
            tag: 'p',
            children: 'vdom'
        },
        {
            tag: 'ul',
            props: { style: 'font-size: 20px' }
            children: [
                {
                    tag: 'li',
                    children: 'a'
                }
                // ....
            ]
        }
    ]
}

22 监听data变化的核心API

  • Object.defineProperty
  • 缺点
    • 深度监听,需要递归到底
    • 无法监听新增属性/删除属性(Vue.set Vue.delete)
    • 无法监听数组,需要特殊处理

23 vue 如何监听 data 变化?

// Object.defineProperty 的基本用法
const data = {}
const name = 'zhangsan'
Object.defineProperty(data, "name", {
    get: function () {
        console.log('get')
        return name  
    },
    set: function (newVal) {
        console.log('set')
        name = newVal
    }
});

// 测试
console.log(data.name)  // get zhangsan
data.name = 'lisi'      // set

24 vue 如何监听数组变化?

  • Object.defineProperty 不能监听数组变化
  • 重新定义原型,重写push pop等方法,实现监听
  • Proxy可以原生支持监听数组的变化

// 触发更新视图

function updateView() {

console.log('视图更新')

}

// 数组方法处理,这里稍微复杂一点

const oldArrayPrototype = Array.prototype

const arrProto = Object.create(oldArrayPrototype); // 创建新对象,原型指向 oldArrayPrototype ,再扩展属性不会影响 oldArrayPrototype

['push', 'pop', 'shift', 'unshift', 'splice'].forEach(method => {

// 重新定义这些新方法,监听数组变化

arrProto[method] = function () {

updateView() // 触发更新视图

oldArrayPrototype[method].call(this, ...arguments) // 调用原有方法

}

})

25 描述响应式原理

  • 监听data变化
  • 组件渲染和更新的流程

26 diff 算法时间复杂度是多少

  • O(n)
  • 是在O(n^3)基础上做了一些调整

27 简述 diff 算法过程

  • patch(elem,vnode) 和 patch(vnode,newVnode)
  • patchVnode 和 addVnodes 和 removeVnodes
  • updateChildren(key的重要性)

        Vue 的 diff 算法以 patch 为入口,首次渲染通过 patch(elem, vnode) 将虚拟 DOM 转化为真实 DOM;更新时通过 patch(vnode, newVnode) 比较新旧虚拟 DOM。节点相同时,调用 patchVnode 递归更新节点内容;对于子节点列表,调用 updateChildren 比较新旧子节点,利用 key 快速定位变化,避免不必要的操作;新增子节点由 addVnodes 创建并插入,移除多余子节点则通过 removeVnodes 完成。整体过程通过最小化 DOM 操作实现高效更新。

28 vue 为何是异步渲染?$nextTick有何用?

  • 异步渲染(以及合并data修改),以提高渲染性能
  • $nextTick 在DOM更新完之后,触发回调

29 vue-router 如何实现路由变化?

  • URL 变化监听

    • Hash 模式:通过监听 window.onhashchange 事件来检测 # 后的部分变化。
    • History 模式:通过监听 popstate 事件来检测浏览器地址栏路径的变化。
  • 匹配路由规则
           路由变化后,Vue Router 会根据当前 URL,利用定义的路由配置表匹配对应的路由规则,找到对应的组件。

  • 更新视图
           匹配到的组件会通过 Vue 的动态组件机制(<router-view>)进行渲染,依托于 Vue 的响应式系统,确保路由变化时视图能够自动更新。

  • 路由钩子
           在路由切换过程中,Vue Router 会执行相应的导航守卫(如全局守卫、路由独享守卫、组件内守卫等),对路由切换进行控制,比如权限校验或数据加载。

30 vue 性能优化

  • 合理使用 v-show 和 v-if
  • 合理使用 computed
  • v-for 时加key,以及避免和v-if 同时使用
  • 自定义事件、DOM事件要及时销毁
  • 合理使用异步组件
  • 合理使用 keep-alive
  • data层级不要太深
  • 使用vue-loader在开发环境做模版编译(预编译)
  • webpack(······)
  • 前端通用的性能优化,如懒加载
  • 使用SSR

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值