Composition Api
Composition Api
是为了解决vue组件里逻辑代码过多而出现的,主要是利用setup
函数把组件的逻辑功能点封装起来,即逻辑复用。
setup
setup
函数在组件创建之前
执行,由于setup
在创建实例前执行,因此没有this
,也不能访问组件声明的属性。参数是props
和context
。如果需要在setup
里创建响应式的变量,那就需要ref
函数把变量封装起来,在setup
函数里使用obj.value
的形式来访问变量。我们也可以在setup
函数里用watch
函数对响应式变量进行监听。使用toRefs
函数对props
的属性进行响应式引用。computed
函数也可以在setup
函数里创建只读的响应式引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import { fetchUserRepositories } from '@/api/repositories' import { ref, onMounted, watch, toRefs, computed } from 'vue'
setup(props) { const { user } = toRefs(props)
const repositories = ref([]) const getUserRepositories = async () => { repositories.value = await fetchUserRepositories(props.user); }
onMounted(getUserRepositories)
watch(user, getUserRepositories)
const searchQuery = ref('') const repositoriesMatchingSearchQuery = computed(() => { return repositories.value.filter(item => item.name.inclueds(searchQuery.value)) })
return { repositories, searchQuery, getUserRepositories, repositoriesMatchingSearchQuery } }
|
组合式函数
这样一看像是把所有逻辑都抽出来封装在setup
函数,而且会使得setup
函数变得很臃肿,所以vue3.0会把上面的例子setup
函数里的逻辑提取到一个独立的组合式函数
。
把逻辑1函数抽象出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { fetchUserRepositories } from '@/api/repositories' import { ref, onMounted, watch } from 'vue'
export default function useUserRepositories(user) { const repositories = ref([]) const getUserRepositories = async () => { repositories.value = await fetchUserRepositories(props.user); } onMounted(getUserRepositories) watch(user, getUserRepositories)
return { repositories, getUserRepositories } }
|
把逻辑2函数抽象出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { ref, computed } from 'vue'
export default function useRepositoryNameSearch(respositories) { const searchQuery = ref('') const repositoriesMatchingSearchQuery = computed(() => { return repositories.value.filter(item => item.name.inclueds(searchQuery.value)) })
return { searchQuery, repositoriesMatchingSearchQuery } }
|
最后在组件中引用,这样子就能把代码逻辑抽象出来,创建个好维护的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import useUserRepositories from '@/composables/useUserRepositories' import useRepositoryNameSearch from '@/composables/useRepositoryNameSearch' import { toRefs } from 'vue'
export default { props: { user: { type: String } }, setup(props) { const { user } = toRefs(props)
const { repositories, getUserRepositories } = useUserRepositories(user) const { searchQuery, repositoriesMatchingSearchQuery } = useRepositoryNameSearch(repositories)
return { repositories: repositoriesMatchingSearchQuery, getUserRepositories, searchQuery, }
} }
|
Teleport
Teleport
是为了解决在组件里也能把内容渲染在父节点以外的问题,常见的使用场景是组件控制弹框,通知信息等全局动画。如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <template> <div class="hello"> <h1>{{ msg }}</h1> <teleport to="#purple-box"> <p>{{ content }}</p> </teleport> </div> <template> <script> export default { data() { return { msg: 'HelloWorld', content: 'hello teleport', } } } </script>
|
片段
以往template
只能包含一个元素,现在支持多个