vue3的新特性
- [组合式 API]
- Teleport
- 片段
- 触发组件选项
- createRenderer API 来自 @vue/runtime-core 创建自定义渲染器
- 单文件组件组合式 API 语法糖
- 单文件组件状态驱动的 CSS 变量
- 单文件组件现在可以包含全局规则或只针对插槽内容的规则
这一篇的主题是组合式API
一,什么是组合式API?
平时使用vue开发的小伙伴们不难发现,在我们封装组件的时候大部分使用组件的选项(data、computed、methods、watch)组织逻辑在大部分情况下都是有效。然而当我们组件变得更大时,逻辑关注点列表增加,组件中的代码量越来越大,导致维护起来变得很困难。
Vue 选项式 API: 按选项类型分组的代码
一个大型组件的示例,其中逻辑关注点是按颜色分组。
这种碎片化使得理解和维护复杂组件变得困难。选项的分离掩盖了潜在的逻辑问题。此外,在处理单个逻辑关注点时,我们必须不断地“跳转”相关代码的选项块。
如果我们能够将与同一个逻辑关注点相关的代码配置在一起会更好。而这正是组合式 API 使我们能够做到的。
于是就有了组合式API
既然我们知道了为什么,我们就可以知道怎么做。为了开始使用组合式 API,我们首先需要一个可以实际使用它的地方。在 Vue组件中,我们将此位置称为 setup
setup 在组件创建之前执行,一旦props被解析,就被充当成API的入口点
由于执行setup时组件实例未被创建,因此setup选项中没有this。这意味着除了props,我们无法访问组件中生命的任何属性–本地状态、计算属性【computed】、方法【methods】
setup的使用:
// src/components/UserRepositories.vue
export default {
components: {
RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
props: {
user: {
type: String }
},
setup(props) {
console.log(props) // { user: '' }
return {
} // 这里返回的任何内容都可以用于组件的其余部分
}
// 组件的“其余部分”
}
代码实战:
1,从假定的外部 API 获取该用户名的仓库,并在用户更改时刷新它
先来看第一段代码⬇️因为我们的 repositories 变量是非响应式的,所以我们要进行修改
// src/components/UserRepositories.vue `setup` function
import {
fetchUserRepositories } from '@/api/repositories'
// 在我们的组件内
setup (props) {
let repositories = []
const getUserRepositories = async () => {
repositories = await fetchUserRepositories(props.user)
}
return {
repositories,
getUserRepositories // 返回的函数与方法的行为相同
}
}
带ref的响应式变量
在 Vue 3.0 中,我们可以通过一个新的 ref 函数使任何响应式变量在任何地方起作用,如下所示:
import {
ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
//ref接受参数并返回它包装在具有value的property对象中,然后可以使用property 修改响应式变量的值
counter.value++
console.log(counter.value) // 1
//在对象中对于包装值就不是必要的,但是在javaScript中基本类型是通过值来传递的
//如 let val1 = 1 const val2 = val1 值的传递
//对象则是通过引用来传递
在任何值周围都有一个包装器对象,这样我们就可以在整个应用程序中安全地传递它,而不必担心在某个地方失去它的响应性。
提示
换句话说,ref 对我们的值创建了一个响应式引用。使用引用的概念将在整个组合式 API 中经常使用。
回到之前的代码,我们来完善它:
// src/components/UserRepositories.vue `setup` function
import {
fetchUserRepositories } from '@/api/repositories'
import {
ref } from 'vue'
// in our component
setup (props) {
const repositories = ref([])
const getUserRepositories = async () => {
repositories.value = await fetchUserRepositories(props.user)
}
return {
repositories,
getUserRepositories
}
}
完成!现在,每当我们调用 getUserRepositories 时,repositories 都将发生变化,视图将更新以反映更改。我们的组件现在应该如下所示:
// src/components/UserRepositories.vue
import {
fetchUserRepo