持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情juejin.cn/post/714765…
prop逐级透传问题
通常情况下,当我们需要从父组件向子组件传递数据时,会使用props,如果有一些多层级嵌套的组件,形成一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅适用props则必须将其沿着组件链逐级传递下去,这样会非常的麻烦:
也就是如果关系特别复杂的组件之间传值的话,如果单纯的用props来传值的话会非常的麻烦且不容易:
注意:中间的组件可能并不关心穿的props的数据,但为了让更深层主要这些数据的组件访问到他们,不得不一层层往下传递,这样导致传递链会非常的长,这个就叫做props逐层透传,这种情况是我们需要去避免的。
解决办法:通过provide和inject来解决props需要逐层透传的问题。一个父组件相对于其所有的后代组件,会作为依赖提供者,任何后代的组件树,无论层级有多深,都可以注入有父组件提供给整条链路的依赖。如图所示:
provide(提供)
要为组件后代提供数据,需要使用到provide选项:
- 直接将provide的值写成对象格式,传递的是静态的值:
- 函数的形式的话,可以访问到当前组件实例的状态,可以为动态的数据:
注意:这样的话不会是注入保持响应式,为了保证注入放和共给房知寄件的响应性连接,我们需要使用computed()函数提供一个计算属性
computed()函数常用于组合式API风格的组件中,但它同样还可以用于补充选项式API风格的某些用例。
注意:上面的用例需要设置app.config.unwrapInjectedRef = true以保证注入会自动解包这个计算属性。这在vue3.3后成为一个默认行为。就不需要设置了。
inject(注入)
要注入(接值)上层组件提供的数据,需要使用inject选项来声明:
注入别名
当以数组形式使用inject,注入的属性会以同名的key暴露到组件实例上。访问的本地属性名和朱汝明是相同的。
如果我们想要用一个不同的本地属性名注入该属性,我们需要在inject选项的属性上使用对象的形式。
上述,组件本地化了原注入名“message”所提供的属性,并将其暴露为this.localMessasge.
注入默认值
默认情况下,inject假设传入的注入名会被某个祖先链上的组件提供,如果该注入名的确没有任何组件提供,则会抛出一个运行时警告。(必须有provide提供者)
如果在注入一个值是不要求必须有提供者,那么我们应该声明一个默认值。和props类似:
使用symbol()作为注入名
我们已经了解如何使用字符串作为注入名,但如果你正在构建大型的应用,包含非常多的依赖提供,或者你正在编写提供给其他开发者使用的组件库,建议最好使用symbol来作为注入名以避免潜在的冲突。
通常推荐在一个单独的文件中导出这些注入名symbol: