前端面经 vue篇

446 阅读4分钟

前端面经 vue篇

vue2.0 与 vue3.0 区别?

响应式系统的重新配置,使用代理替换对象.define属性,使用代理优势:
可直接监控阵列类型的数据变化
监听的目标是对象本身,不需要像Object.defineProperty那样遍历每个属性,有一定的性能提升
可拦截应用、拥有密钥、有等13种方法,以及Object.define属性没有办法
直接添加对象属性/删除
新增组合API,更好的逻辑重用和代码组织
模板编译时间优化,将一些静态节点编译成常量
slot优化,采取槽编译成懒人功能,拿槽渲染的决定留给子组件
代码结构调整,更方便树摇动,使其更小
  1. 数据绑定不同

2.0使用Object.defineProperty来劫持对象属性的geter和seter操作,当数据发生改变时发出通知

// 数据
let data = {
	title: '',
	// 备份数据
	_data: {}
}
// 定义特性
Object.defineProperty(data, 'title', {
	// 定义特性属性或者特性方法
	// 取值方法
	get() {
		// console.log('get')
		// 注意:不能通过自身属性取值
		// return this.title
		// 返回备份的数据
		return this._data.title;
	},
	// 赋值方法
	set(value) {
		// this指向对象
		// 注意:不能为自身属性赋值
		// this.title = value
		// 我们可以向备份数据中存储
		this._data.title = value;
		// console.log('set')
		// 更新视图
		updateView(this._data)
	}
})
// 视图模板
let tpl = document.getElementById('app').innerHTML
// 实现更新视图的方法
function updateView(data) {
	// 处理模板
	let html = tpl.replace(/{{(w+)}}/g, (match, $1) => {
		// 从data中获取数据
		return data[$1] || ''
	})
	// 更新视图
	document.getElementById('app').innerHTML = html;
}

3.0使用ES6的新特性 porxy 原理: 通过ES6的新特性Proxy来进行劫持数据

var obj = {};
var obj1 = new Proxy(obj, {
    // target就是第一个参数obj, receive就是返回的obj(返回的proxy对象)
    get: function (target, key, receive) {
        // 返回该属性值
        return target[key];
    },
    set: function (target, key, newVal, receive) {
        // 执行赋值操作
        target[key] = newVal;
    }
})

总结: vue2.x 版本中的数据双向绑定不能检测到下标的变化; proxy可以劫持整个对象,并返回一个新对象 proxy的优点: 使用proxy不污染对象, 会返回一个新对象, defineProperty是注入型的, 会破坏源对象 使用proxy只需要监听整个源对象的属性, 不需要循环使用Object.defineProperty监听对象的属性 使用proxy可以获得对象属性的更多参数, 使用defineProperty只能获取到监听属性的新值newValue

  1. 生命周期的变化 3.0添加setup

setup 存在于 created与 beforeCreated之间

1.  Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
2.  beforeDestroy改名为 beforeUnmount
3.  destroyed改名为 unmounted
4.  Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
5.  beforeCreate===>setup()
6.  created=======>setup()
7.  beforeMount ===>onBeforeMount
8.  mounted=======>onMounted
9.  beforeUpdate===>onBeforeUpdate
10. updated =======>onUpdated
11. beforeUnmount ==>onBeforeUnmount
12. unmounted =====>onUnmounted

3. 创建vue实例

vue2: new Vue({})
vue3: vue.createApp({})
  1. 根节点 3.0允许多个根节点

  2. vue3.0 hook模式(与react的hook类似) hook模式

// ref 是 vue 3.0 的一个重大变化,其作用为创建响应式的值

import { ref } from 'vue'

// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
  setup () {
    // 定义一个不需要改变的数据
    const btnText = '点这个按钮上面的数字会变'
    // 定义一个 count 的响应式数据,并赋值为 0
    const count = ref(0)
    // 定义一个函数,修改 count 的值。
    const countAdd = () => {
      count.value++
    }
    // 导出一些内容给上面的模板区域使用
    return {
      btnText,
      count,
      countAdd
    }
  }
}


// reactive 是 vue 3.0 的一个重大变化,其作用为创建响应式的对象或数组
import { reactive } from 'vue'
// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
  setup () {
    // 定义一个 state 的响应式对象数据,并赋值
    const state = reactive({
      name: 'FungLeo',
      sex: 'boy',
      address: '上海'
    })
    console.log(state)
    // 定义一个函数,修改 state 的值。
    const addressChange = () => {
      state.address += '浦东'
    }
    // 导出一些内容给上面的模板区域使用
    return {
      state,
      addressChange
    }
  }
}

reactive 与 ref 的区别

  1. 从定义数据方面: ref通常用来定义基本类型数据 reactive用来定义对象/数组类型数据 ref也可以用来定义对象/数组类型的数据,内部会通过reactive转为代理对象 2)从原理方面: ref通过Object.defineProperty的get和set实现数据代理 reactive使用Proxy实现数据代理,并通过Reflect操作源对象内部的数据 3)从使用方面: ref操作数据需要 .value , template中不需要 reactive都不需要.value
  1. 计算属性 computed
// 需要使用计算属性,也需要从 vue 中导出引入
import { ref, computed } from 'vue'

    // 计算属性,使用计算函数并命名,然后在 return 中导出即可
    const bigCount = computed(() => {
      return count.value * 10
    })
 
    // 导出一些内容给上面的模板区域使用
    return {
      count,
      bigCount,
    }

7. Vue3.0带来了什么改变?

1.性能的提升,打包大小减少41%,初次渲染快55%, 更新渲染快133%,内存减少54%
2.使用Proxy代替defineProperty实现响应式,重写虚拟DOM的实现和Tree-Shaking
3.拥抱TypeScript
4.新的特性
  Composition API(组合API)
  setup配置
  ref与reactive
  watch与watchEffect
  provide与inject
5.新的内置组件
  Fragment
  Teleport
  Suspense

持续更新......