为什么要去掉Vue构造函数?
vue3响应式数据有哪些变化?
createApp创建Vue应用
Vue2的弊端:
- use,minxin,component...的代码会影响到所有的Vue应用。不利于隔离。
- 构造函数集成了太多的功能,不利于trees hacking。
- 没有把组件实例根Vue应用这两个概念分开,通过new创建的对象既是一个应用又是一个组件。
Vue3提供了一种全新的创建Vue应用的方式createApp
将use、mixin、component挂在到实例中。当我们使用链式调用的方式创建出来的应用在使用use、mixin、component的时候只会影响到当前应用。
数据响应式
Vue2和Vue3完成数据响应式都是在相同的生命周期。实现的方式的区别在于:
Vue2是通过Object.defineProperty递归遍历对象中的每一个属性完成数据响应式。当数据量大时遍历的属性非常多,非常的浪费性能。在创建时只会执行一次,之后往对象中加入属性是检测不到的。
Vue3是通过Proxy进行数据响应式,Proxy的效率本事就比Object.defineProperty更高。Proxy是动态读取,只需要new Porxy就可以完成数据绑定。
模板
可以写多个根节点
v-model
- 为了更好的支持双向数据绑定Vue3去掉了.sync修饰符,由v-model的参数替代。
- :modelValue,@update:modelValue 可以简写为v-model
- 可以添加自定义修饰符
v-if,v-for
v-if的优先级比v-for更高
异步组件
defineAsyncComponent函数实现,返回值为组件实例。
获取响应式数据
| API | 传入 | 返回 | 备注 |
|---|---|---|---|
reactive | plain-object | 对象代理 | 深度代理对象中的所有成员 |
readonly | plain-object or proxy | 对象代理 | 只能读取代理对象中的成员,不可修改 |
ref | any | { value: ... } | 对value的访问是响应式的 如果给value的值是一个对象, 则会通过 reactive函数进行代理如果已经是代理,则直接使用代理 |
computed | function | { value: ... } | 当读取value值时, 会根据情况决定是否要运行函数 |
应用:
- 如果想要让一个对象变为响应式数据,可以使用
reactive或ref - 如果想要让一个对象的所有属性只读,使用
readonly - 如果想要让一个非对象数据变为响应式数据,使用
ref - 如果想要根据已知的响应式数据得到一个新的响应式数据,使用
computed
composition api
有了composition api,配合reactivity api,可以在组件内部进行更加细粒度的控制,使得组件中不同的功能高度聚合,提升了代码的可维护性。对于不同组件的相同功能,也能够更好的复用。 相比于option api,composition api中没有了指向奇怪的this,所有的api变得更加函数式,这有利于和类型推断系统比如TS深度配合。
setup
// component
export default {
setup(props, context){
// 该函数在组件属性被赋值后立即执行,早于所有生命周期钩子函数
// props 是一个对象,包含了所有的组件属性值
// context 是一个对象,提供了组件所需的上下文信息
}
}
context对象的成员
| 成员 | 类型 | 说明 |
|---|---|---|
| attrs | 对象 | 同vue2的this.$attrs |
| slots | 对象 | 同vue2的this.$slots |
| emit | 方法 | 同vue2的this.$emit |
生命周期函数
| vue2 option api | vue3 option api | vue 3 composition api |
|---|---|---|
| beforeCreate | beforeCreate | 不再需要,代码可直接置于setup中 |
| created | created | 不再需要,代码可直接置于setup中 |
| beforeMount | beforeMount | onBeforeMount |
| mounted | mounted | onMounted |
| beforeUpdate | beforeUpdate | onBeforeUpdate |
| updated | updated | onUpdated |
| beforeDestroy | ==改== beforeUnmount | onBeforeUnmount |
| destroyed | ==改==unmounted | onUnmounted |
| errorCaptured | errorCaptured | onErrorCaptured |
| - | ==新==renderTracked | onRenderTracked |
| - | ==新==renderTriggered | onRenderTriggered |
新增钩子函数说明:
| 钩子函数 | 参数 | 执行时机 |
|---|---|---|
| renderTracked | DebuggerEvent | 渲染vdom收集到的每一次依赖时 |
| renderTriggered | DebuggerEvent | 某个依赖变化导致组件重新渲染时 |
DebuggerEvent:
- target: 跟踪或触发渲染的对象
- key: 跟踪或触发渲染的属性
- type: 跟踪或触发渲染的方式