让我们一起走向未来
🎓作者简介:全栈领域优质创作者
🌐个人主页:百锦再@新空间代码工作室
💡座右铭:坚持自己的坚持,不要迷失自己!要快乐
目录
- 让我们一起走向未来
- 1. **Props 透传**
- 2. **Provide 和 Injection**
- 3. **Provide 设置只读**
- 4. **Injection 默认值**
- 5. **Symbol 作为 Provide/Inject 的键**
- 总结
- 在这里插入图片描述
- Vue 注入的应用场景
- 完整举例
- 1. 响应式数据的注入
- 2. 使用Symbol作为注入名
- 3. 应用级别的依赖注入
好的,下面是一个完整的 Vue 3 示例,涵盖了您所要求的几个功能:Props 透传、Provide 和 Injection、Provide 设置只读、Injection 默认值、以及 Symbol 做 Provide 注入名。所有的代码都放在 <script setup>
语法中,结合了 Vue 3 的组合式 API。
1. Props 透传
在子组件中,不需要显式地声明 Props,Vue 会自动透传父组件的 Props。
<!-- ParentComponent.vue -->
<template>
<ChildComponent :message="parentMessage" />
</template>
<script setup>
const parentMessage = 'Hello from parent!'
</script>
<!-- ChildComponent.vue -->
<template>
<div>{{ message }}</div>
</template>
<script setup>
// 自动透传父组件的所有 Props
const props = defineProps()
</script>
2. Provide 和 Injection
父组件使用 provide
提供数据,子组件通过 inject
注入数据。
<!-- ParentComponent.vue -->
<template>
<ChildComponent />
</template>
<script setup>
import { provide } from 'vue'
const user = {
name: 'John Doe',
age: 30
}
// 使用 provide 提供数据
provide('userInfo', user)
</script>
<!-- ChildComponent.vue -->
<template>
<div>{{ user.name }} is {{ user.age }} years old.</div>
</template>
<script setup>
import { inject } from 'vue'
// 注入父组件提供的数据
const user = inject('userInfo')
if (user) {
console.log(user.name) // 输出: John Doe
}
</script>
3. Provide 设置只读
使用 readonly
来将数据设置为只读,防止子组件修改父组件提供的数据。
<!-- ParentComponent.vue -->
<template>
<ChildComponent />
</template>
<script setup>
import { provide, readonly } from 'vue'
const user = {
name: 'Jane Doe',
age: 28
}
// 使用 readonly 设置为只读
provide('userInfo', readonly(user))
</script>
<!-- ChildComponent.vue -->
<template>
<div>{{ user.name }} is {{ user.age }} years old.</div>
</template>
<script setup>
import { inject } from 'vue'
const user = inject('userInfo')
// user 是只读的,无法修改
if (user) {
console.log(user.name) // 输出: Jane Doe
}
</script>
4. Injection 默认值
如果 inject
不能找到提供的值,你可以为 inject
设置默认值。
<!-- ParentComponent.vue -->
<template>
<ChildComponent />
</template>
<script setup>
import { provide } from 'vue'
const defaultUser = {
name: 'Default User',
age: 25
}
// 提供数据
provide('userInfo', defaultUser)
</script>
<!-- ChildComponent.vue -->
<template>
<div>{{ user.name }} is {{ user.age }} years old.</div>
</template>
<script setup>
import { inject } from 'vue'
const user = inject('userInfo', { name: 'Injected Default User', age: 20 })
// 如果没有提供数据,将使用默认值
console.log(user.name) // 输出: Default User
</script>
5. Symbol 作为 Provide/Inject 的键
使用 Symbol
作为 provide
和 inject
的键,可以避免名称冲突。
<script setup>
// keys.js
export const myInjectionKey = Symbol()
</script>
<!-- ParentComponent.vue -->
<script setup>
// 在供给方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'
provide(myInjectionKey, {
/* 要提供的数据 */
})
</script>
// 使用 Symbol 作为键提供数据
provide(userInfoSymbol, user)
<!-- ChildComponent.vue -->
<script setup>
// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'
const injected = inject(myInjectionKey)
</script>
总结
- Props 透传:子组件通过
defineProps()
自动接收父组件传递的所有 Props。 - Provide 和 Injection:父组件使用
provide
提供数据,子组件使用inject
获取数据。 - Provide 设置只读:通过
readonly
创建只读数据,避免子组件修改。 - Injection 默认值:通过
inject
设置默认值,当没有提供数据时使用默认值。 - Symbol 作为 Provide/Inject 的键:使用
Symbol
来作为provide
和inject
的键,避免键名冲突。
这些示例展示了 Vue 3 的组合式 API 在 <script setup>
中如何结合使用,从而让组件间的数据共享更加灵活和简洁。
Vue 注入的应用场景
Vue 的依赖注入(Dependency Injection, DI)机制通过 provide
与 inject
API,实现了跨组件层级间的数据与服务透明传递,主要应用场景包括:
- 全局状态管理:在应用中,可以使用依赖注入来管理全局状态,将状态提供给各个组件,而无需显式传递。
- 服务注入:在大型应用中,可以将一些通用的服务(如API服务、验证服务等)注入到各个组件中,从而实现代码的复用和模块化。
- 国际化:可以通过依赖注入将翻译服务提供给各个组件,使得组件可以根据当前语言显示相应的文本。
- 插件开发:共享插件的功能或配置。
- 跨层级通信:在多层级组件中共享数据或方法。
- 响应式数据:提供响应式数据,使得多个组件可以共享并响应相同的数据变化。
完整举例
1. 响应式数据的注入
父组件 提供一个响应式的 count
变量,子组件 注入后可以访问并修改它,所有注入该响应式变量的组件都会自动更新。
<!-- 父组件 -->
<template>
<div>
<button @click="count++">Increment</button>
<child-component></child-component>
</div>
</template>
<script setup>
import { provide, ref } from 'vue';
const count = ref(0);
provide('count', count);
</script>
<!-- 子组件 -->
<template>
<div>{{ count }}</div>
</template>
<script setup>
import { inject } from 'vue';
const count = inject('count');
</script>
2. 使用Symbol作为注入名
为了避免命名冲突,可以使用Symbol作为注入名。
// keys.js
export const myInjectionKey = Symbol();
<!-- 父组件 -->
<template>
<child-component></child-component>
</template>
<script setup>
import { provide } from 'vue';
import { myInjectionKey } from './keys.js';
provide(myInjectionKey, 'Secret Message');
</script>
<!-- 子组件 -->
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { inject } from 'vue';
import { myInjectionKey } from './keys.js';
const message = inject(myInjectionKey);
</script>
3. 应用级别的依赖注入
通过 createApp
实例的 provide
方法在应用级别提供了一个依赖,这样在整个应用中的任意组件都可以注入这个依赖。
// main.js
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.provide('appMessage', 'Hello from Vue App!');
app.mount('#app');
<!-- 任意组件 -->
<template>
<div>{{ appMessage }}</div>
</template>
<script setup>
import { inject } from 'vue';
const appMessage = inject('appMessage');
</script>
这些例子展示了如何在Vue中使用依赖注入来实现跨组件的数据共享和服务提供,有助于提高项目的可维护性和可扩展性。