前端面经 vue篇
vue2.0 与 vue3.0 区别?
响应式系统的重新配置,使用代理替换对象.define属性,使用代理优势:
可直接监控阵列类型的数据变化
监听的目标是对象本身,不需要像Object.defineProperty那样遍历每个属性,有一定的性能提升
可拦截应用、拥有密钥、有等13种方法,以及Object.define属性没有办法
直接添加对象属性/删除
新增组合API,更好的逻辑重用和代码组织
模板编译时间优化,将一些静态节点编译成常量
slot优化,采取槽编译成懒人功能,拿槽渲染的决定留给子组件
代码结构调整,更方便树摇动,使其更小
- 数据绑定不同
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
- 生命周期的变化 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({})
-
根节点 3.0允许多个根节点
-
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 的区别
- 从定义数据方面: ref通常用来定义基本类型数据 reactive用来定义对象/数组类型数据 ref也可以用来定义对象/数组类型的数据,内部会通过reactive转为代理对象 2)从原理方面: ref通过Object.defineProperty的get和set实现数据代理 reactive使用Proxy实现数据代理,并通过Reflect操作源对象内部的数据 3)从使用方面: ref操作数据需要 .value , template中不需要 reactive都不需要.value
- 计算属性 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
持续更新......