6、依赖注入
祖先组件向后代组件传值
6.1 provide()
提供一个值,可以被后代组件注入。
provide()
接受两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值。
与注册生命周期钩子的 API 类似,
provide()
必须在组件的setup()
阶段同步调用。
6.2 inject()
注入一个由祖先组件或整个应用 (通过 app.provide()
) 提供的值。
第一个参数是注入的 key。Vue 会遍历父组件链,通过匹配 key 来确定所提供的值。如果父组件链上多个组件对同一个 key 提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过 key 匹配到值,inject()
将返回 undefined
,除非提供了一个默认值。
第二个参数是可选的,即在没有匹配到 key 时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值。如果默认值本身就是一个函数,那么你必须将 false
作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。
与注册生命周期钩子的 API 类似,inject()
必须在组件的 setup()
阶段同步调用。
18_composition/89_composition_provide_inject.html
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>依赖注入</title>
</head>
<body>
<div id='app'>
<button @click="count++">点击{{count}}次</button>
<my-parent></my-parent>
</div>
</body>
<template id="parent">
<div>
我是父组件
<my-child></my-child>
</div>
</template>
<template id="child">
<div>
我是子组件
-{{ count }}-<button @click="add">加10</button>- {{ test }} - {{ fn() }}
</div>
</template>
<script src='../lib/vue.global.js'></script>
<script>
const { createApp, ref, provide, inject } = Vue
const Child = {
template: '#child',
setup () {
const count = inject('count')
// 获取祖先组件的数据
const add = inject('add')
// 设置默认值
const test = inject('test', '测试')
// 如果默认值是一个函数,请设置第三个参数为false
const fn = inject('fn', () => {
console.log(10000)
}, false)
return {
count, add, test, fn
}
}
}
const Parent = {
template: '#parent',
components: {
MyChild: Child
}
}
createApp({
components: {
MyParent: Parent
},
setup () {
const count = ref(10)
const add = () => {
count.value += 10
}
// 数据提供者
provide('count', count)
provide('add', add)
return {count}
}
}).mount('#app')
</script>
</html>