[TOC]

Vue3新特性

Vue2的核心模块和历史遗留问题

image.png

  1. Flow.js 类型校验 已经停止维护了
  2. Vue2 内部运行时,是直接执行浏览器API的, 顾在跨终端方案中带来问题。
  3. Vue 2 响应式并不是真正意义上的代理,而是基于 Object.defineProperty() 实现的
  4. Option API 在组织代码较多组件的时候不易维护。

    从七个方面了解Vue3新特性。

  5. RFC机制

  6. 响应式系统
  7. 自定义渲染器image.png
  8. 全部模块使用TypeScript重构
  9. Composition API 组合语法
  10. 新的组件 Fragment、Teleport 和 Suspense
  11. Vite

image.png

组合式API

介绍

setup组件选项

setup选项是一个接受 props 和 context的函数,将 setup返回的所有内容都暴露给组件的其他部分(计算属性 方法 生命周期钩子)以及组件模版。

带 ref的响应式变量

通过 一个新的 ref 函数使任何响应式变量在任何地方起作用。
pass-by-reference-vs-pass-by-value-animation.gif
在任何周围都有一个封装对象,这样我们就可以在整个应用中安全的传递它,而不必担心某个地方失去它的响应式。

在 setup内注册生命周期钩子

组合式API的生命周期钩子与选项式API的名称相同,但前缀为 on 即 mounted -> onMounted
这些函数接受一个回调,当钩子被组件调用时,该回调将被执行。

import { ref ,onMonted } from 'vue'

watch响应式更改

Vue导入的watch 函数执行相同的操作,它接受3个参数:

  • 一个想要侦听的 响应式引用 或 getter函数
  • 一个回调
  • 可选的配置选项 ``` import { ref ,watch } from ‘vue’

const counter = ref(0) watch(counter,(newValue,oldValue)=>{ console.log(‘The new counter value is:’ + counter.value) })

<a name="GUB81"></a>
### 独立的 computed 属性
Vue 导入的 computed 函数在Vue组件外部创建计算属性。

import { ref ,computed } from ‘vue’ const counter = ref(0) const twiceTheCounter = computed(()=> counter.value * 2)

<a name="rOfcC"></a>
## Setup
使用 单文件组件代码示例的语法。
<a name="BMa35"></a>
### Props 
setup函数中的 props 是响应式的,当传入新的props时, 它将被更新。<br />因为 props是响应式的, 不能使用ES6解构,它会消除prop的响应式。<br />如果需要解构 prop 可以在 setup函数中使用 toRefs 函数来完成此操作。

// MyBook.vue

import { toRefs } from ‘vue’; setup(props){ const { title } = toRefs(props); console.log(title.value) }

// 如果 title 是 可选的 prop, 则传入的 props中可能没有 title。 // 在这种情况下,toRefs 将不会为 title创建一个 ref. // 需要使用 toRef替代它

// MyBook.vue

import { toRef } from ‘vue’ setup(props){ const title = toRef(props,’title’) console.log(title.value) }


<a name="gt85c"></a>
### Context
context是一个普通js对象。

// MyBook.vue export defalut { setup(props,{ attrs,slots,emit,expose }){ } }

attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。请注意,与 props 不同,attrs 和 slots 的 property 是**非**响应式的。如果你打算根据 attrs 或 slots 的更改应用副作用,那么应该在 onBeforeUpdate 生命周期钩子中执行此操作。
<a name="rr4KO"></a>
### 访问组件的property
执行 setup时,只能访问 以下 propery

- props
- attrs
- slots
- emit
<a name="njYqZ"></a>
### 结合模版使用
``` ### 使用渲染函数 返回一个渲染函数将阻止我们返回任何其他东西。
可以通过调用 expose 来解决这个问题,给它传递一个对象,其中定义的property将可以被外部组件实例访问。 ``` import { h, ref } from 'vue' export default { setup(props, { expose }) { const count = ref(0) const increment = () => ++count.value expose({ increment }) return () => h('div', count.value) } } ``` ### 使用 this **在 setup() 内部,this 不是该活跃实例的引用**,因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同。这使得 setup() 在和其它选项式 API 一起使用时可能会导致混淆。 ## 生命周期钩子 你可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。
下表包含如何在 [setup ()](https://v3.cn.vuejs.org/guide/composition-api-setup.html) 内部调用生命周期钩子: | 选项式 API | Hook inside setup | | --- | --- | | beforeCreate | Not needed* | | created | Not needed* | | beforeMount | onBeforeMount | | mounted | onMounted | | beforeUpdate | onBeforeUpdate | | updated | onUpdated | | beforeUnmount | onBeforeUnmount | | unmounted | onUnmounted | | errorCaptured | onErrorCaptured | | renderTracked | onRenderTracked | | renderTriggered | onRenderTriggered | | activated | onActivated | | deactivated | onDeactivated | 因为 setup 是围绕 beforeCreate 和 created生命周期钩子运行的,所以不需要显式定义它们.
换句话说,在这些钩子中编写的任何代码都应该直接在setup函数中编写。 ## Provide / Inject ```

```

响应式

添加响应式

修改响应式对象

模版引用

Teleport

Teleport提供了一种干净的方法,允许我们控制在dom中哪个节点下渲染 html,而不必求助于全局状态或者将其拆分为为两个组件。

高阶指南

响应性

深入响应式原理

响应性基础