组合式API
旧的vue2规范中主张选项式的api来规范代码,比如在data中设置响应式的变量,methods中定义方法,computed中定义计算属性......
这种结构难免会使代码逻辑变的割裂,不顺畅,增加阅读难度。在组件的功能变得复杂时这些缺点更加明显。
Vue3 提出使用组合式API来解决这个问题,他们被写在setup中。顾名思义,就是倡导在一个函数setup中流畅地实现逻辑,但并不实现具体的函数,而是将函数从别的js中定好以后引入。
使用方式
-
setp接受参数:props和context,通过return暴露的内容在整个组件的其余地方都能访问
-
setup返回的所有内容都暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。 -
setup中设置响应式的数据:ref VS reactive,可以创建响应式的引用。
const counter = ref(0), counter是一个包裹着value=0的对象。但是ref只能处理基础类型。引用类型需要reactive:
reactive({ value: [] })。由此响应的数据可以自由的定义,而不是集中定义在data中 -
在setup内注册生命周期钩子:mounted → onMounted
-
watch的使用:watch(counter,(newval,oldval)=>{},options)
-
路由的用法有些不一样,因为setup中没有this,不能用this.$router.push而是import { useRouter } from 'vue-router’
const router = useRouter()
应用
我们来用组合式api实现一个简单的列表:
<template>
<div class="test-container">
<div class="top-container">
<list-filter></list-filter>
</div>
<div class="list-container">
<a-table :dataSource="tableData" :columns="tableTitle" size="small" />
</div>
</div>
</template>
<script>
import listFilter from './Filter.vue'
import { onMounted, ref } from 'vue'
import { tableDataSearch, getTableTitle } from './tableDataSearch'
export default {
components: {
listFilter,
},
setup () {
let tableData = ref([])
let filterParams = ref([])
const tableTitle = getTableTitle()
const getList = async () => {
tableData.value = tableDataSearch(filterParams)
}
onMounted(getList)
return {
getList,
tableTitle,
filterParams: ref({}),
tableData,
}
},
}
可以看到响应式的变量,方法,生命周期函数都定义在setup中,通过return暴露给组建的其他部分或者其他组件。复杂的方法如 tableDataSearch 在js文件中定义好了引入到setup中,来保持setup的简洁。
注意
-
setup在组件创建之前运行 → 尽量避免在setup中使用this
-
响应式的数据使用解构赋值会破坏响应性, 如 const {user} = props。
不过可以这样避免: const {user} = toRefs(props)
如果user是一个可选的属性,需要用toRef: const user = toRef(props,’user’)
-
setup里的书写顺序是重要的,有一次onMounted(functionA)写在functionA前面就报错了