总概1) 性能提升
- 打包大小减少 41%
- 初次渲染快 55%,更新渲染快 133%
- 内存减少 54%
- 使用 Proxy 代替 defineProperty 实现数据响应式
- 重写虚拟 DOM 的实现和 Tree-Shaking
- Composition (组合) API
- setup
- ref 和 reactive
- computed 和 watch
- 新的生命周期函数
- provide 与 inject
- 新组件
- Fragment - 文档碎片
- Teleport - 瞬移组件的位置
- Suspense - 异步加载组件的 loading 界面
- 其它 API 更新
- 全局 API 的修改
- 将原来的全局 API 转移到应用对象
- 模板语法变化
- 新的 option , 所有的组合 API 函数都在此使用,只在初始化时执行一次
- 函数如果返回对象,对象中的属性或方法,模板中可以直接使用
- 作用:定义一个数据的响应式
- 语法:const xxx = ref(initValue):
- 创建一个包含响应式数据的引用(reference)对象
- js 中操作数据:xxx.value
- 模板中操作数据:不需要.value
- 一般用来定义一个基本类型的响应式数据
- 作用: 定义多个数据的响应式
- const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
- 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
- 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
- 核心:
- 对象:通过 defineProperty 对对象的已有属性值的读取和修改进行劫持(监视/拦截)
- 数组:通过重写数组更新数组一系列更新元素的方法来实现元素修改的劫持
- 问题:
- 对象直接新添加的属性或删除已有属性,界面不会自动更新
- 直接通过下标替换元素或更新 length,界面不会自动更新 arr[1] = {}
- 核心:
- 通过 Proxy(代理):拦截对 data 任意属性的任意(13 种)操作,包括属性值的读写,属性的添加,属性的删除等...
- 通过 Reflect(反射):动态对被代理对象的相应属性进行特定的操作
- 文档:
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy(opens new window)
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
- setup 执行的时机
- 在 beforeCreate 之前执行(一次),此时组件对象还没有创建
- this 是 undefined , 不能通过 this 来访问 data/computed/methods / props
- 其实所有的 composition API 相关回调函数中也都不可以
- setup 的返回值
- 一般都返回一个对象:为模板提供数据,也就是模板中可以直接使用此对象中的所有属性/方法
- 返回对象中的属性会与 data 函数返回对象的属性合并成为组件对象的属性
- 返回对象中的方法会与 methods 中的方法合并成功组件对象的方法
- 如果有重名,setup 优先
- 注意:
- 一般不要混合使用:methods 中可以访问 setup 提供的属性和方法 , 但在 setup 方法中不能访问 data 和 methods
- setup 不能是一个 async 函数:因为返回值不再是 return 的对象 , 而是 promise,模板看不到 return 对象中的属性数据
- setup 的参数
- setup(props,context) / setup(props,{attrs,slots,emit})
- props:包含 props 配置声明且传入了的所有属性的对象
- attrs:包含没有在 props 配置中声明的属性的对象 , 相当于 this.$attrs
- slots:包含所有传入的插槽内容的对象,相当于 this.$slots
- emit:用来分发自定义事件的函数,相当于 this.$emit
- 是 Vue3 的 composition API 中 2 个最重要的响应式 API
- ref 用来处理基本类型数据,reactive 用来处理对象(递归深度响应式)
- 如果用 ref 对象/数组,内部会自动将对象/数组转换为 reactive 的代理对象
- ref 内部:通过给 value 属性添加 getter/setter 来实现对数据的劫持
- reactive 内部:通过使用 Proxy 来实现对对象内部所有数据的劫持,并通过 Reflect 操作对象内部数据
- ref 的数据操作:在 js 中要.value,在模板中不需要(内部解析模板时会自动添加.value)