Vue3 provide/inject用法总结
1. 基本概念
provide/inject 是 Vue3 中实现跨层级组件通信的方案,类似于 React 的 Context。它允许父组件向其所有子孙组件注入依赖,无论层级有多深。
1.1 基本语法
// 提供方(父组件)
const value = ref('hello')
provide('key', value)// 注入方(子孙组件)
const value = inject('key')
2. 基础用法
2.1 提供静态值
<!-- Parent.vue -->
<script setup>
import { provide } from 'vue'// 提供静态值
provide('theme', 'dark')
provide('language', 'zh-CN')
</script><!-- Child.vue -->
<script setup>
import { inject } from 'vue'// 注入值
const theme = inject('theme')
const language = inject('language')
</script><template><div :class="theme"><p>Current Language: {{ language }}</p></div>
</template>
2.2 提供响应式数据
<!-- Parent.vue -->
<script setup>
import { provide, ref } from 'vue'const count = ref(0)
const updateCount = () => {count.value++
}// 提供响应式数据和更新方法
provide('count', {count,updateCount
})
</script><!-- Child.vue -->
<script setup>
import { inject } from 'vue'const { count, updateCount } = inject('count')
</script><template><div><p>Count: {{ count }}</p><button @click="updateCount">Increment</button></div>
</template>
3. 进阶用法
3.1 使用 Symbol 作为 key
// injection-keys.ts
export const COUNT_KEY = Symbol('count')
export const THEME_KEY = Symbol('theme')
<!-- Parent.vue -->
<script setup lang="ts">
import { provide } from 'vue'
import { COUNT_KEY, THEME_KEY } from './injection-keys'const count = ref(0)
provide(COUNT_KEY, count)
provide(THEME_KEY, 'dark')
</script><!-- Child.vue -->
<script setup lang="ts">
import { inject } from 'vue'
import { COUNT_KEY, THEME_KEY } from './injection-keys'const count = inject(COUNT_KEY)
const theme = inject(THEME_KEY)
</script>
3.2 提供默认值
<script setup>
import { inject } from 'vue'// 使用静态默认值
const theme = inject('theme', 'light')// 使用工厂函数作为默认值
const now = inject('timestamp', () => Date.now())
</script>
3.3 只读数据
<!-- Parent.vue -->
<script setup>
import { provide, ref, readonly } from 'vue'const count = ref(0)
// 提供只读版本,防止子组件修改
provide('count', readonly(count))// 提供更新方法
provide('updateCount', () => {count.value++
})
</script><!-- Child.vue -->
<script setup>
import { inject } from 'vue'const count = inject('count')
const updateCount = inject('updateCount')
</script>
4. 实际应用场景
4.1 主题系统
<!-- ThemeProvider.vue -->
<script setup>
import { provide, ref } from 'vue'const theme = ref('light')
const toggleTheme = () => {theme.value = theme.value === 'light' ? 'dark' : 'light'
}provide('theme', {theme,toggleTheme
})
</script><template><div :class="theme.value"><slot></slot></div>
</template><!-- 使用组件 -->
<script setup>
import { inject } from 'vue'const { theme, toggleTheme } = inject('theme')
</script><template><button @click="toggleTheme">Switch to {{ theme === 'light' ? 'dark' : 'light' }} mode</button>
</template>
4.2 多语言系统
<!-- I18nProvider.vue -->
<script setup>
import { provide, ref } from 'vue'const locale = ref('en')
const messages = {en: {greeting: 'Hello',farewell: 'Goodbye'},zh: {greeting: '你好',farewell: '再见'}
}const t = (key) => messages[locale.value][key]
const setLocale = (lang) => {locale.value = lang
}provide('i18n', {locale,t,setLocale
})
</script><!-- 使用组件 -->
<script setup>
import { inject } from 'vue'const { t, setLocale, locale } = inject('i18n')
</script><template><div><select v-model="locale"><option value="en">English</option><option value="zh">中文</option></select><p>{{ t('greeting') }}</p></div>
</template>
4.3 状态管理
<!-- Store.vue -->
<script setup>
import { provide, reactive } from 'vue'const store = reactive({user: null,todos: [],addTodo(text) {this.todos.push({ id: Date.now(), text, completed: false })},toggleTodo(id) {const todo = this.todos.find(t => t.id === id)if (todo) {todo.completed = !todo.completed}}
})provide('store', store)
</script><!-- TodoList.vue -->
<script setup>
import { inject } from 'vue'const store = inject('store')
</script><template><div><inputv-model="newTodo"@keyup.enter="store.addTodo(newTodo)"><ul><liv-for="todo in store.todos":key="todo.id"@click="store.toggleTodo(todo.id)">{{ todo.text }}</li></ul></div>
</template>
5. TypeScript 支持
5.1 类型定义
// types.ts
export interface ThemeContext {theme: Ref<'light' | 'dark'>toggleTheme: () => void
}export const ThemeSymbol = Symbol('theme')
5.2 带类型的 provide/inject
<script setup lang="ts">
import { provide, inject } from 'vue'
import { ThemeContext, ThemeSymbol } from './types'// 提供方
provide<ThemeContext>(ThemeSymbol, {theme: ref('light'),toggleTheme: () => { /* ... */ }
})// 注入方
const theme = inject<ThemeContext>(ThemeSymbol)
</script>
6. 最佳实践
-
使用 Symbol 作为 key
const MyKey = Symbol('my-key') provide(MyKey, value)
-
提供只读数据
provide('data', readonly(data))
-
集中管理 injection key
// keys.ts export const THEME_KEY = Symbol('theme') export const I18N_KEY = Symbol('i18n')
-
使用组合式函数封装
// useTheme.ts export function useTheme() {const theme = inject(THEME_KEY)if (!theme) {throw new Error('useTheme must be used within ThemeProvider')}return theme }
7. 注意事项
-
响应性
- 确保提供响应式数据时使用 ref 或 reactive
- 注意数据的可变性和只读性
-
默认值
- 提供合理的默认值
- 考虑使用工厂函数作为默认值
-
类型安全
- 使用 TypeScript 定义接口
- 使用 Symbol 作为 key
-
性能考虑
- 避免提供过大的数据结构
- 合理划分提供的数据范围
通过合理使用 provide/inject,我们可以有效地管理跨组件通信,构建可维护的组件树。但要注意避免过度使用,以免造成数据流向难以追踪的问题。
相关文章:
Vue3 provide/inject用法总结
1. 基本概念 provide/inject 是 Vue3 中实现跨层级组件通信的方案,类似于 React 的 Context。它允许父组件向其所有子孙组件注入依赖,无论层级有多深。 1.1 基本语法 // 提供方(父组件) const value ref(hello) provide(key, …...

Linux——网络基础(1)
文章目录 目录 文章目录 前言 一、文件传输协议 应用层 传输层 网络层 数据链路层 数据接收与解封装 主机与网卡 数据传输过程示意 二、IP和MAC地址 定义与性质 地址格式 分配方式 作用范围 可见性与可获取性 生活例子 定义 用途 特点 联系 四、TCP和UDP协…...

【记录】日常|从零散记录到博客之星Top300的成长之路
文章目录 shandianchengzi 2024 年度盘点概述写作风格简介2024年的创作内容总结 shandianchengzi 2024 年度盘点 概述 2024年及2025年至今我创作了786即84篇文章,加上这篇就是85篇。 很荣幸这次居然能够入选博客之星Top300,这个排名在我之前的所有年份…...

【二分查找】力扣373. 查找和最小的 K 对数字
给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。 请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。 示例 1: 输入: nums1 [1,7,11], nums2 …...

池化层Pooling Layer
1. 定义 池化是对特征图进行的一种压缩操作,通过在一个小的局部区域内进行汇总统计,用一个值来代表这个区域的特征信息,常用于卷积神经网络(CNN)中。 2. 作用 提取代表性信息的同时降低特征维度,具有平移…...

力扣算法题——11.盛最多水的容器
目录 💕1.题目 💕2.解析思路 本题思路总览 借助双指针探索规律 从规律到代码实现的转化 双指针的具体实现 代码整体流程 💕3.代码实现 💕4.完结 二十七步也能走完逆流河吗 💕1.题目 💕2.解析思路…...

自由学习记录(32)
文件里找到切换颜色空间 fgui中的 颜色空间是一种总体使用前的设定 颜色空间,和半透明混合产生的效果有差异,这种问题一般可以产生联系 动效就是在fgui里可以编辑好,然后在unity中也准备了对应的调用手段,可以详细的使用每一个具…...
VScode+Latex (Recipe terminated with fatal error: spawn xelatex ENOENT)
使用VSCode编辑出现Recipe terminated with fatal error: spawn xelatex ENOENT问题咋办? 很好解决,大概率的原因是因为latex没有添加到系统环境变量中,所有设置的编译工具没有办法找到才出现的这种情况。 解决方法: winR 然后输…...
「蓝桥杯题解」蜗牛(Java)
题目链接 这道题我感觉状态定义不太好想,需要一定的经验 import java.util.*; /*** 蜗牛* 状态定义:* dp[i][0]:到达(x[i],0)最小时间* dp[i][1]:到达 xi 上方的传送门最小时间*/public class Main {static Scanner in new Scanner(System.in);static f…...
PHP EOF (Heredoc) 详解
PHP EOF (Heredoc) 详解 PHP 中的 EOF(End Of File)是一种非常有用的语法特性,允许开发者创建多行字符串。它特别适合于创建格式化文本,如配置文件、HTML 模板等。本文将详细讲解 PHP EOF 的用法、优势以及注意事项。 什么是 EOF? EOF 是一种特殊的字符串定义方式,它允…...
pyautogui操控Acrobat DC pro万能PDF转Word,不丢任何PDF格式样式
为了将PDF转换脚本改为多进程异步处理,我们需要确保每个进程独立操作不同的Acrobat窗口。以下是实现步骤: 实现代码 import os import pyautogui import time import subprocess import pygetwindow as gw from multiprocessing import Pooldef conver…...
Day32:字符串的复制
在 Python 中,字符串的复制是指创建一个新的字符串,它的内容与原字符串相同。字符串是不可变的对象,这意味着你不能直接修改字符串的内容,但是可以通过复制来创建新的字符串进行操作。字符串的复制在一些情况下非常有用࿰…...

基于Mybatis继承AbstractRoutingDataSource使用自定义注解实现动态数据源
一:实现 方式一:继承AbstractRoutingDataSource使用自定义注解实现 环境:springboot3 MyBatis3 mysql-connector8 DataSourceKeyEnum枚举类 有几个数据源就配置几个枚举类,和数据源数量一一对应 class DataSourceKeyEnum{D…...
ZooKeeper 数据模型
ZooKeeper 数据模型 ZooKeeper 拥有层次化的命名空间,类似分布式文件系统,但每个节点不仅能有子节点,还可关联数据。节点路径为规范的绝对路径,用斜杠分隔,无相对引用。路径命名有如下约束: 路径名不能包…...

【VUE】Vue2中Vue.extend方法
在 Vue.js 2.x 版本中,Vue.extend() 方法被用于创建一个新的 Vue 子类,可以在该子类上扩展一些属性、指令和组件选项等,然后进行实例化。 比如,可以在创建一些类似 loading 式的函数式插件时,使用: 在 Vue…...

MaskGAE论文阅读
What’s Behind the Mask: Understanding Masked Graph Modeling for Graph Autoencoders 碎碎念:一篇论文看四天,效率也没谁了(捂脸) 看一点忘一点,虽然在本子上有记录,但还是忘,下次看一点在博客上记一点启发 本来很…...

Mybatis-plus 更新 Null 的策略踩坑记
一个bug 在一个管理页面,有一个非必填字段被设置成空了并提交更新,再次打开的时候,发现字段还在,并没有被更新成功。 使用的数据库映射框架是 Mybatis-plus ,对于Mybatis 在更新字段的时候会对空进行校验,…...

Oracle迁移DM数据库
Oracle迁移DM数据库 本文记录使用达梦官方数据迁移工具DTS,将Oracle数据库的数据迁移至达梦数据库。 1 数据准备 2 DTS工具操作步骤 2.1 创建工程 打开DTS迁移工具,点击新建工程,填写好工程信息,如图: 2.2 新建迁…...

HTML特殊符号的使用示例
目录 一、基本特殊符号的使用 1、空格符号: 2、小于号 和 大于号: 3、引号: 二、版权、注册商标符号的使用 1、版权符号:© 2、注册商标符号: 三、数学符号的使用 四、箭头符号的使用 五、货币符号的使用…...
数据结构基础之《(15)—排序算法小结》
一、排序算法的稳定性 1、稳定性是指同样大小的样本再排序之后不会改变相对次序 2、对基础类型来说,稳定性毫无意义 比如:3和3没有区别。《潜伏》里说同样两个一百元大钞,你能告诉我哪一个是高尚的那一个是龌龊的么 3、对非基础类型来说&a…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...