什么是组合式api?
大型组件的 选项式API代码非常冗长,逻辑相关联的代码,分布分散,跳转代码不利于阅读理解。
如果我们将与同一个逻辑关注点相关的代码配置在一起 这便是组合式 API
在 Vue 组件中,我们将此位置称为 setup
处于 beforeCreate 和 created 生命周期
在 setup 中 应该避免使用 this,因为组件实例还未被创建。
setup 的调用发生在 data property、computed property 或 methods 被解析之前,所以它们无法在 setup 中被获取。
setup 选项应该是一个接受 props 和 context 的函数。
setup 返回的所有内容都将暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。
为了保证setup中暴露的内容 具有响应式
在定义变量时,需要配合Vue的ref(reference)创建了一个响应式引用来使用
带ref的响应式setup
ref 需要 .value 访问值,setup 的 return 在模板中做了自动浅解包,须省略.value
let count = ref(0)
let list = ref([])
const { user } = toRefs(props)
reactive 使对象具有响应式
在普通的周期钩子前面加上on
这些函数接受一个回调,当生命周期钩子被组件调用时,该回调将被执行。
onMounted(fun)
直接导入watch函数
watch(ref, (newValue, oldValue) => {} , {})
从 Vue 导入的 computed 函数
第一个参数:一个类似 getter 的回调函数,返回的是一个只读的响应式引用
let doubleCounter = computed(() => counter.value * 2) // 返回 只读的响应式引用 通过 .value 访问
同样是导入 provide
两个参数:
readonly(vlaue)
同理导入 inject
两个参数:
setup的逻辑块封装到一个组合式函数中
解决代码冗长的问题
// 将原本在不同位置相关的逻辑内容放入一个组合式函数中
export default function xxxFunction(user) {
const repositories = ref([])
// 请求数据的方法
const getUserRepositories = async () => {
repositories.value = await fetchUserRepositories(user.value)
}
// mounted 生命周期钩子
onMounted(getUserRepositories)
// 创建监听
watch(user, getUserRepositories)
return {
repositories,
getUserRepositories
}
}
setup中调用相应的方法
setup (props) {
const { user } = toRefs(props)
const { repositories, getUserRepositories } = useUserRepositories(user) // 调用
// ···
return { // 放回内容会被注入
repositories,
getUserRepositories,
xxxx,
}
}
props
通过使用 toRefs 使对 props 的解构赋值任具有响应性
const {xx, xxx} = toRefs(props)
若某些 prop 可能不存在,则需要使用如下方法:
const xxxx= toRef(props, 'propName')
content (非响应性)
包含 attrs、slots、emit、expose
setup(props, { attrs, slots, emit, expose }) {}
不要对 attrs、slots 进行解构,因为它们的内容会更新
若要根据 attrs 或 slots 更改应用(effect)副作用,需在 onBeforeUpdate
生命周期钩子中执行此操作。
expose 组件的方法通过模板 ref 暴露给父组件
模板中定义的 ref 可通过如下方式在setup中被调用:
声明同名的 ref 并从 setup() 返回
<template>
<div ref="root">XXXXX</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup() {
const root = ref(null)
onMounted(() => {
// DOM 元素将在初始渲染后分配给 ref
console.log(root.value) // XXXXX
})
return {
root
}
}
}
</script>
语法糖特点:
模板中强烈建议使用 大驼峰 格式 与引入组件保持一致性;这也有助于区分原生的自定义元素。
区别:
<component :is="XxxXxxx" /><!-- is需要绑定,因为不再是字符串了 --/>
const props = defineProps({
foo: String
})
无需引用,仅能在
中使用
默认不开放 需要defineExposeconst slots = useSlots() // setupContext.slots
const attrs = useAttrs() // setupContext.slots