vuejs3.0 从入门到精通——provide、inject、mixins、extends
provide、inject、mixins、extends
一、provide
用于提供可以被后代组件注入的值。
1 2 3 | interface ComponentOptions { provide?: object | (( this : ComponentPublicInstance) => object) } |
-
- interface ComponentOptions:定义了一个名为 ComponentOptions 的接口。在 Vue.js 中,组件选项是一个对象,用于定义组件的行为、属性等。
- provide?:provide 是 ComponentOptions 接口中的一个可选属性。provide 属性用于在组件的子孙组件中注入依赖,是 Vue 的依赖注入机制的一部分。
- object | ((this: ComponentPublicInstance) => object):这是 provide 属性的类型定义,表示 provide 可以是一个对象,或者是一个返回对象的函数。
-
- object:表示 provide 可以是一个对象,该对象包含可注入的属性。
- ((this: ComponentPublicInstance) => object):表示 provide 也可以是一个函数,该函数返回一个对象。函数的 this 上下文被类型化为 ComponentPublicInstance,这是 Vue 组件实例的公共部分。这样的类型注解确保了函数内部的 this 上下文具有 ComponentPublicInstance 类型,从而可以使用该类型的属性和方法。
-
- provide和inject通常成对一起使用,使一个祖先组件作为其后代组件的依赖注入方,无论这个组件的层级有多深都可以注入成功,只要他们处于同一条组件链上。
- 这个provide选项应当是一个对象或是返回一个对象的函数。这个对象包含了可注入其后代组件的属性。你可以在这个对象中使用Symbol类型的值作为key。
示例:
基本使用方式:
1 2 3 4 5 6 7 8 | const s = Symbol() export default { provide: { foo: 'foo' , [s]: 'bar' } } |
-
-
-
- const s = Symbol(): 这里创建了一个唯一的 Symbol 类型的变量 s。Symbol 是 JavaScript 中的一种数据类型,每个 Symbol 值都是唯一的。这意味着即使你创建了多个 Symbol,它们也不会相等。
- export default {...}: 这部分代码导出一个对象,这个对象将被用作 Vue 组件的选项。
- provide: {...}: provide 是 Vue 组件的一个选项,它允许你向下传递数据,使得后代组件可以通过 inject 选项获取这些数据。
- foo: 'foo': 在 provide 对象中,foo 是一个键,其对应的值是一个字符串 'foo'。这意味着,任何后代组件都可以通过 inject 选项获取到 'foo' 这个值,使用的键是 'foo'。
- [s]: 'bar': 这里使用了计算属性名称(Computed Property Names)的特性,它允许你使用变量作为对象的键。在这里,变量 s(一个 Symbol)被用作键,字符串 'bar' 是对应的值。这意味着,后代组件可以通过 inject 选项和 Symbol s 来获取到 'bar' 这个值。
-
-
1 2 3 4 5 6 7 8 9 10 11 12 | export default { data() { return { msg: 'foo' } } provide() { return { msg: this .msg } } } |
-
- data 方法
data() 是一个方法,它返回一个对象。这个对象就是该 Vue 组件的局部状态(即数据)。
在返回的对象中,msg 是一个属性,其值为 'foo'。这意味着在该组件的模板和方法中,你可以通过 this.msg 来访问这个数据属性。
-
- provide 方法
provide() 是另一个方法,它也返回一个对象。这个对象中的属性和值将被提供给该组件的后代组件。
在返回的对象中,msg 是一个属性,其值通过 this.msg 从组件的 data 中获取。这意味着后代组件可以通过 inject 选项来注入这个 msg,并访问其值 'foo'。
msg
将不会是响应式的。二、inject
用于声明要通过从上层提供方匹配并注入进当前组件的属性。
1 2 3 4 5 6 7 8 9 10 11 12 | interface ComponentOptions { inject?: ArrayInjectOptions | ObjectInjectOptions } type ArrayInjectOptions = string[] type ObjectInjectOptions = { [key: string | symbol]: | string | symbol | { from?: string | symbol; default ?: any } } |
ComponentOptions 接口定义了一个可选的 inject 属性,其类型可以是 ArrayInjectOptions 或 ObjectInjectOptions。这使得开发者可以在使用 Vue 组件时更灵活地注入属性或者从父组件中获取属性。
简要概述一下这两种类型:
-
- ArrayInjectOptions:是一个字符串数组,数组中的每个字符串代表要从父组件中注入的属性名。
- ObjectInjectOptions:是一个对象,该对象的每个键值对都表示一个要注入的属性。键是属性名,值可以是字符串、符号,或者一个具有 from 和 default 属性的对象。其中,from 属性表示从哪里注入属性,default 属性表示如果父组件没有提供该属性,那么将使用的默认值。
请注意,注入绑定并非响应式的。这是有意为之的一个设计。如果要注入的值是一个响应式对象,那么这个对象上的属性将会保留响应性。请看配合响应性一节获取更多细节。
示例:
基本使用方法:
1 2 3 4 5 6 | export default { inject: [ 'foo' ], created() { console.log( this .foo) } } |
使用注入的值作为 props 的默认值:
1 2 3 4 5 6 7 8 9 10 | const Child = { inject: [ 'foo' ], props: { bar: { default () { return this .foo } } } } |
使用注入的值作为 data:
1 2 3 4 5 6 7 8 | const Child = { inject: [ 'foo' ], data() { return { bar: this .foo } } } |
注入项可以选择是否带有默认值:
1 2 3 4 5 | const Child = { inject: { foo: { default : 'foo' } } } |
如果需要从不同名字的属性中注入,请使用from
指明来源属性。
1 2 3 4 5 6 7 8 | const Child = { inject: { foo: { from: 'bar' , default : 'foo' } } } |
和props默认值类似,对于非原始数据类型的值,你需要使用工厂函数:
1 2 3 4 5 6 7 8 | const Child = { inject: { foo: { from: 'bar' , default : () => [1, 2, 3] } } } |
三、mixins
https://cn.vuejs.org/api/options-composition.html#mixins
一个包含组件选项对象的数组,这些选项都将被混入到当前组件的实例中。
1 2 3 | interface ComponentOptions { mixins?: ComponentOptions[] } |
这是一个 TypeScript 的接口声明,名为 ComponentOptions。这个接口表示 Vue 组件的选项对象,用来定义 Vue 组件的配置和行为。
在这个接口中,声明了一个名为 mixins 的属性,它的类型是 ComponentOptions[],也就是 ComponentOptions 的数组。mixins 属性是可选的,所以它的定义后面有一个 ? 符号。
在 Vue 2 中,mixins 是创建可重用组件逻辑的主要方式。尽管在 Vue 3 中保留了 mixins 支持,但对于组件间的逻辑复用,使用组合式 API 的组合式函数(https://cn.vuejs.org/guide/reusability/composables.html)是现在更推荐的方式。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | const mixin = { created() { console.log(1) } } createApp({ created() { console.log(2) }, mixins: [mixin] }) // => 1 // => 2 |
在这部分,我们使用createApp
方法创建一个新的Vue应用。这个应用对象包含两个主要的部分:
-
- 一个
created
生命周期钩子,当应用被创建时,它会打印数字2
。 mixins: [mixin]
这部分代码表示我们要在这个应用中混入mixin
对象。这意味着mixin
中的所有内容(在这种情况下,是created
钩子)将被添加到这个应用中,就好像它们直接在应用对象中定义一样。
- 一个
mixins
选项接受一个 mixin对象数组。这些mixin对象可以像普通的实例对象一样包含实例选项,它们将使用一定的选项合并逻辑与最终的选项进行合并。举例来说,如果你的mixin包含了一个created
钩子,而组件自身也有一个,那么这两个函数都会被调用。
Mixin 钩子的调用顺序与提供它们的选项顺序相同,且会在组件自身的钩子前被调用。
四、extends
要继承的“基类”组件。
1 2 3 | interface ComponentOptions { extends ?: ComponentOptions } |
使一个组件可以继承另一个组件的组件选项。
从实现角度来看,extends几乎和mixins相同。通过extends指定的组件将会当作第一个mixin来处理。
然而,extends和mixins表达的是不同的目标。mixins选项基本用于组合功能,而extends则一般更关注继承关系。
同mixins一样,所有选项(setup() 除外)都将使用相关的策略进行合并。
示例:
1 2 3 4 5 6 | const CompA = { ... } const CompB = { extends : CompA, ... } |
123456789101112131415161718不建议用于组合式 API
extends
是为选项式 API 设计的,不会处理 setup() 钩子的合并。
在组合式 API 中,逻辑复用的首选模式是“组合”而不是“继承”。如果一个组件中的逻辑需要复用,考虑将相关逻辑提取到组合式函数中。
如果你仍然想要通过组合式 API 来“继承”一个组件,可以在继承组件的 setup() 中调用基类组件的 setup():
import
Base from
'./Base.js'
export
default
{
extends
: Base,
setup(props, ctx) {
return
{
...Base.setup(props, ctx),
// 本地绑定
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具