Vue核心知识:透传Props,注入Inject_前端

让我们一起走向未来

🎓作者简介:全栈领域优质创作者
🌐个人主页:百锦再@新空间代码工作室
💡座右铭:坚持自己的坚持,不要迷失自己!要快乐


Vue核心知识:透传Props,注入Inject_数据_02


目录

  • 让我们一起走向未来
  • 1. **Props 透传**
  • 2. **Provide 和 Injection**
  • 3. **Provide 设置只读**
  • 4. **Injection 默认值**
  • 5. **Symbol 作为 Provide/Inject 的键**
  • 总结
  • 在这里插入图片描述
  • Vue 注入的应用场景
  • 完整举例
  • 1. 响应式数据的注入
  • 2. 使用Symbol作为注入名
  • 3. 应用级别的依赖注入


Vue核心知识:透传Props,注入Inject_vue.js_03

好的,下面是一个完整的 Vue 3 示例,涵盖了您所要求的几个功能:Props 透传、Provide 和 Injection、Provide 设置只读、Injection 默认值、以及 Symbol 做 Provide 注入名。所有的代码都放在 <script setup> 语法中,结合了 Vue 3 的组合式 API。

1. Props 透传

Vue核心知识:透传Props,注入Inject_javascript_04

在子组件中,不需要显式地声明 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

Vue核心知识:透传Props,注入Inject_ide_05

父组件使用 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 设置只读

Vue核心知识:透传Props,注入Inject_ide_06

使用 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 默认值

Vue核心知识:透传Props,注入Inject_数据_07

如果 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 的键

Vue核心知识:透传Props,注入Inject_javascript_08

使用 Symbol 作为 provideinject 的键,可以避免名称冲突。

<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>

总结

  1. Props 透传:子组件通过 defineProps() 自动接收父组件传递的所有 Props。
  2. Provide 和 Injection:父组件使用 provide 提供数据,子组件使用 inject 获取数据。
  3. Provide 设置只读:通过 readonly 创建只读数据,避免子组件修改。
  4. Injection 默认值:通过 inject 设置默认值,当没有提供数据时使用默认值。
  5. Symbol 作为 Provide/Inject 的键:使用 Symbol 来作为 provideinject 的键,避免键名冲突。

这些示例展示了 Vue 3 的组合式 API 在 <script setup> 中如何结合使用,从而让组件间的数据共享更加灵活和简洁。

Vue 注入的应用场景

Vue核心知识:透传Props,注入Inject_ide_09

Vue 的依赖注入(Dependency Injection, DI)机制通过 provideinject API,实现了跨组件层级间的数据与服务透明传递,主要应用场景包括:

  1. 全局状态管理:在应用中,可以使用依赖注入来管理全局状态,将状态提供给各个组件,而无需显式传递。
  2. 服务注入:在大型应用中,可以将一些通用的服务(如API服务、验证服务等)注入到各个组件中,从而实现代码的复用和模块化。
  3. 国际化:可以通过依赖注入将翻译服务提供给各个组件,使得组件可以根据当前语言显示相应的文本。
  4. 插件开发:共享插件的功能或配置。
  5. 跨层级通信:在多层级组件中共享数据或方法。
  6. 响应式数据:提供响应式数据,使得多个组件可以共享并响应相同的数据变化。

完整举例

1. 响应式数据的注入

Vue核心知识:透传Props,注入Inject_数据_10

父组件 提供一个响应式的 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作为注入名

Vue核心知识:透传Props,注入Inject_ide_11

为了避免命名冲突,可以使用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. 应用级别的依赖注入

Vue核心知识:透传Props,注入Inject_前端_12

通过 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中使用依赖注入来实现跨组件的数据共享和服务提供,有助于提高项目的可维护性和可扩展性。

Vue核心知识:透传Props,注入Inject_前端_13