provide & inject
provide并inject启用类似于2.x provide/inject
选项的依赖项注入。两者都只能在setup()当前活动实例期间调用。
import { provide, inject } from 'vue' const ThemeSymbol = Symbol() const Ancestor = { setup() { provide(ThemeSymbol, 'dark') } } const Descendent = { setup() { const theme = inject(ThemeSymbol, 'light' /* optional default value */) return { theme } } }
inject接受可选的默认值作为第二个参数。如果未提供默认值,并且在Provide
上下文中找不到该属性,则inject返回undefined
。
使用响应式
为了保持提供的值和注入的值之间的响应式,可以使用ref:
// in provider const themeRef = ref('dark') provide(ThemeSymbol, themeRef) // in consumer const theme = inject(ThemeSymbol, ref('light')) watch(() => { console.log(`theme set to: ${theme.value}`) })
模板引用
使用Composition API时,响应式引用和模板引用的概念是统一的。为了获得对模板中元素或组件实例的引用,我们可以像往常一样声明ref并从中返回setup():
<template> <div ref="root"></div> </template> <script> import { ref, onMounted } from 'vue' export default { setup() { const root = ref(null) onMounted(() => { // the DOM element will be assigned to the ref after initial render console.log(root.value) // <div/> }) return { root } } } </script>
用作模板ref的ref的行为与其他任何ref一样:它们是响应式的,可以传递到组合函数中(或从中返回)。
- Render/ JSX的用法
export default { setup() { const root = ref(null) return () => h('div', { ref: root }) // with JSX return () => <div ref={root}/> } }
- 内部用法 v-for
Composition API template refs do not have special handling when used inside v-for. Instead, use function refs (new feature in 3.0) to perform custom handling:
<template> <div v-for="(item, i) in list" :ref="el => { divs[i] = el }"> {{ item }} </div> </template> <script> import { ref, reactive, onBeforeUpdate } from 'vue' export default { setup() { const list = reactive([1, 2, 3]) const divs = ref([]) // make sure to reset the refs before each update onBeforeUpdate(() => { divs.value = [] }) return { list, divs } } } </script>
defineComponent
该功能仅用于类型推断。为了让TypeScript知道应该将对象视为组件定义,以便可以推断传递给的数据的类型,这是必需的setup()。这是无操作行为的明智选择。它需要一个组件定义并按原样返回参数。
import { defineComponent } from 'vue' export default defineComponent({ props: { foo: String }, setup(props) { props.foo // <- type: string } })