组合式 API
为什么需要它
能够将与同一个逻辑关注点相关的代码配置在一起(解决选项式api的痛点)
基础

// src/components/UserRepositories.vueexport default {components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },props: {user: { type: String }},setup(props) {console.log(props) // { user: '' }return {} // 这里返回的任何内容都可以用于组件的其余部分}// 组件的“其余部分”}
声明响应式变量
基本类型+数组
在 Vue 3.0 中,我们可以通过一个新的 ref 函数使任何响应式变量在任何地方起作用,如下所示:
import { ref } from 'vue'const counter = ref(0)console.log(counter) // { value: 0 }console.log(counter.value) // 0counter.value++console.log(counter.value) // 1
其实本质就是将值传递转换成引用传递(拿到指针)
引用类型
reactive:返回对象的响应式副本
const obj = reactive({ count: 0 })
生命周期的变化

这些函数接受一个回调函数,当钩子被组件调用时将会被执行:
// MyBook.vueexport default {setup() {// mountedonMounted(() => {console.log('Component is mounted!')})}}
状态逻辑复用
根据组合api,我们可以抽离公用的状态逻辑,不再使用mixin
function useMouse() {const x = ref(0)const y = ref(0)const update = e => {x.value = e.pageXy.value = e.pageY}onMounted(() => {window.addEventListener('mousemove', update)})onUnmounted(() => {window.removeEventListener('mousemove', update)})return { x, y }}// 在组件中使用该函数const Component = {setup() {const { x, y } = useMouse()// 与其它函数配合使用const { z } = useOtherLogic()return { x, y, z }},template: `<div>{{ x }} {{ y }} {{ z }}</div>`}

内置组件
Teleport
背景
Vue 鼓励我们通过将 UI 和相关行为封装到组件中来构建 UI。我们可以将它们嵌套在另一个内部,以构建一个组成应用程序 UI 的树。
然而,有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置。
一个常见的场景是创建一个包含全屏模式的组件。在大多数情况下,你希望模态的逻辑存在于组件中,但是模态的定位很快就很难通过 CSS 来解决,或者需要更改组件组合。
Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件。
const app = Vue.createApp({});app.component('modal-button', {template: `<button @click="modalOpen = true">Open full screen modal! (With teleport!)</button><teleport to="body"><div v-if="modalOpen" class="modal"><div>I'm a teleported modal!(My parent is "body")<button @click="modalOpen = false">Close</button></div></div></teleport>`,data() {return {modalOpen: false}}})app.mount('#app')
