Vue 高频面试题

1. 虚拟dom是什么?

// 本质是一个 js 对象 ==>下一步转化为 document.createElement() 执行
let obj = {
	target:'ul', // 目标
	attr: 'abc', // 属性
	children: [{ // 子元素
		target:'li',
		attr: 'def',
	}]
}

将 直接操作dom(影响浏览器性能)=>两份 js对象(虚拟dom)的比较(diff算法 即执行效率上的问题)局部更新

2. Vue data()为什么是一个函数?

闭包 =>特性?数据的私密性,延长变量生命周期
为了保持各个组件的数据隔离

3. Vue父子组件生命周期加载的时候执行顺序?

创建前后+挂载前后:
beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

4. Vue2 / 3中的响应式原理

4.1 vue2.x的响应式

  • 官方描述:

    • 当你把一个普通的 JavaScript 对家传入Vue 实例作为 data 选项,Vue 将遍历此对象所有的property,并使用 Object.defineProperty 把这些 property 全部转为 getter / setter。
  • 实现原理:

    • 对象类型:通过 Object.defineProperty() 对属性的读取、修改进行拦截(数据劫持)。

    • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

      Object.defineProperty(data, 'count', {
          get () {}, 
          set () {}
      })
      
  • 存在问题:

    • 新增属性、删除属性, 界面不会更新。
    • 直接通过下标修改数组, 界面不会自动更新。

4.2 Vue3.x的响应式

  • 实现原理:
    • 通过 Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。

    • 通过 Reflect(反射): 对源对象的属性进行操作。

    • MDN文档中描述的 ProxyReflect

      new Proxy(data, {
      	// 拦截读取属性值
          get (target, prop) {
          	return Reflect.get(target, prop)
          },
          // 拦截设置属性值或添加新属性
          set (target, prop, value) {
          	return Reflect.set(target, prop, value)
          },
          // 拦截删除属性
          deleteProperty (target, prop) {
          	return Reflect.deleteProperty(target, prop)
          }
      })
      
      proxy.name = 'tom'   
      

5. Vue 组件通讯的方式

  1. props$emit父子组件
  2. 自定义事件(即中央事件总线eventBus)(上下级组件(跨多级)通讯
  3. attrs (收集除emit和props之外剩余参数和方法,用于兜底)
  4. $parent子向父组件通讯
  5. $refs父向子组件通讯
  6. provide / inject上下级组件(跨多级)通讯
  7. vuex全局组件

6. vuex 中 mutation / action 区别

  • mutation原子操作;必须同步代码;
  • action可包含多个 mutation;可包含异步代码;

7. vue组件中data为什么是函数?

我们知道JS中实例对象是通过构造函数来创建的,每个构造函数可以new出多个实例,每个实例都会继承原型上的属性和方法。那么在vue中,一个vue组件就是一个vue实例,当一个组件被复用多次就会创建多个实例。

  • 如果data是对象,那么多次复用的组件在某一处改变了data数据,就会影响到其他处复用这个组件的地方,因为对象是引用数据类型,是对内存地址的引用,牵一发而动全身。
  • 而如果data是一个函数的话,那么我们每次创建一个新的实例之后,就会调用这个新的data函数,返回一个新的对象,也就是给每一个data对象定义了一个新的内存地址,自己维护自己的数据。所以为了保证每个组件data的独立性,或者说是组件的可复用性,data就必须是一个函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值