[Vue3 API] – 组合式 API

# 组合式 API

本节例子中代码使用的单文件组件语法

# setup

一个组件选项,在创建组件之前执行,一旦 props 被解析,并作为组合式 API 的入口点

  • 入参:

    • {Data} props
    • {SetupContext} context
  • 类型声明

interface Data {
[key: string]: unknown
}
interface SetupContext {
attrs: Data
slots: Slots
emit: (event: string, ...args: unknown[]) => void
}
function setup(props: Data, context: SetupContext): Data

TIP

若要获取传递给 setup() 的参数的类型推断,请使用 defineComponent 是需要的。

  • 示例:

    使用模板:

    <!-- MyBook.vue -->
    <template>
    <div>{{ readersNumber }} {{ book.title }}</div>
    </template>
    <script>
    import { ref, reactive } from 'vue'
    export default {
    setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // expose to template
    return {
    readersNumber,
    book
    }
    }
    }
    </script>
    

    使用渲染函数:

    // MyBook.vue
    import { h, ref, reactive } from 'vue'
    export default {
    setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // 请注意,我们需要在这里显式地暴露ref值
    return () => h('div', [readersNumber.value, book.title])
    }
    }
    
  • 参考:组合式 API setup

# 生命周期钩子

可以使用直接导入的 onX 函数注册生命周期钩子:

import { onMounted, onUpdated, onUnmounted } from 'vue'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}

这些生命周期钩子注册函数只能在 setup() 期间同步使用,因为它们依赖于内部全局状态来定位当前活动实例 (此时正在调用其 setup() 的组件实例)。在没有当前活动实例的情况下调用它们将导致错误。

组件实例上下文也是在生命周期钩子的同步执行期间设置的,因此在生命周期钩子内同步创建的侦听器和计算属性也会在组件卸载时自动删除。

选项 API 生命周期选项和组合式 API 之间的映射

  • beforeCreate -> use setup()

  • created -> use setup()

  • beforeMount -> onBeforeMount

  • mounted -> onMounted

  • beforeUpdate -> onBeforeUpdate

  • updated -> onUpdated

  • beforeUnmount -> onBeforeUnmount

  • unmounted -> onUnmounted

  • errorCaptured -> onErrorCaptured

  • renderTracked -> onRenderTracked

  • renderTriggered -> onRenderTriggered

  • 参考:组合式 API 生命周期钩子

# Provide / Inject

provideinject 启用依赖注入。只有在使用当前活动实例的 setup() 期间才能调用这两者。

  • 类型声明
interface InjectionKey<T> extends Symbol {}
function provide<T>(key: InjectionKey<T> | string, value: T): void
// without default value
function inject<T>(key: InjectionKey<T> | string): T | undefined
// with default value
function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
// with factory
function inject<T>(
key: InjectionKey<T> | string,
defaultValue: () => T,
treatDefaultAsFactory: true
): T

Vue 提供了一个 InjectionKey 接口,该接口是扩展 Symbol 的泛型类型。它可用于在提供者和消费者之间同步 inject 值的类型:

import { InjectionKey, provide, inject } from 'vue'
const key: InjectionKey<string> = Symbol()
provide(key, 'foo') // 提供非字符串值将导致错误
const foo = inject(key) // foo 的类型: string | undefined

如果使用字符串 key 或非类型化 symbols,则需要显式声明 inject 值的类型:

const foo = inject<string>('foo') // string | undefined
  • 参考

    • Provide / Inject
    • 组合式 API Provide / Inject

# getCurrentInstance

getCurrentInstance 支持访问内部组件实例,用于高阶用法或库的开发。

import { getCurrentInstance } from 'vue'
const MyComponent = {
setup() {
const internalInstance = getCurrentInstance()
internalInstance.appContext.config.globalProperties // 访问 globalProperties
}
}

getCurrentInstance 只能在 setup 或生命周期钩子中调用。

如需在 setup 或生命周期钩子外使用,请先在 setup 中调用 getCurrentInstance() 获取该实例然后再使用。

const MyComponent = {
setup() {
const internalInstance = getCurrentInstance() // works
const id = useComponentId() // works
const handleClick = () => {
getCurrentInstance() // doesn't work
useComponentId() // doesn't work
internalInstance // works
}
onMounted(() => {
getCurrentInstance() // works
})
return () =>
h(
'button',
{
onClick: handleClick
},
`uid: ${id}`
)
}
}
// 在组合式函数中调用也可以正常执行
function useComponentId() {
return getCurrentInstance().uid
}
以上是[Vue3 API] – 组合式 API的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>