news 2026/4/15 5:54:15

VUE3:深入浅出探究pinia、provide\inject在多层组件页面是怎么使用的

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VUE3:深入浅出探究pinia、provide\inject在多层组件页面是怎么使用的

1. Pinia 状态管理

什么是 Pinia?

Pinia是 Vue 3 官方推荐的状态管理库,可以理解为一个"全局数据仓库"。

为什么需要它?想象一下,你有一个购物车数据,需要在多个页面(首页、商品页、结算页)共享。如果用 props 一层层传递会很麻烦,Pinia 就是解决这个问题的。

安装 Pinia

npm install pinia

使用步骤

第一步:在 main.js 中注册 Pinia
// main.js import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) const pinia = createPinia() app.use(pinia) app.mount('#app')
第二步:创建 Store(数据仓库)
// src/stores/counter.js import { defineStore } from 'pinia' import { ref, computed } from 'vue' // defineStore 第一个参数是 store 的唯一标识(名字) export const useCounterStore = defineStore('counter', () => { // ========== state(数据)========== // 就像组件中的 ref,存放响应式数据 const count = ref(0) const name = ref('小明') // ========== getters(计算属性)========== // 就像组件中的 computed const doubleCount = computed(() => count.value * 2) // ========== actions(方法)========== // 修改数据的方法 function increment() { count.value++ } function decrement() { count.value-- } // 异步操作也可以放在 actions 中 async function asyncIncrement() { // 模拟接口请求 await new Promise(resolve => setTimeout(resolve, 1000)) count.value++ } // 必须 return 出去才能在组件中使用 return { count, name, doubleCount, increment, decrement, asyncIncrement } })
第三步:在组件中使用 Store

爷爷组件 (GrandParent.vue)

<template> <div class="grandparent"> <h2>👴 爷爷组件</h2> <p>从 Pinia 获取的 count: {{ counterStore.count }}</p> <p>双倍 count: {{ counterStore.doubleCount }}</p> <button @click="counterStore.increment">爷爷点击 +1</button> <!-- 嵌套父组件 --> <ParentComponent /> </div> </template> <script setup> import { useCounterStore } from '@/stores/counter' import ParentComponent from './ParentComponent.vue' // 获取 store 实例,直接使用即可 const counterStore = useCounterStore() </script>

父组件 (ParentComponent.vue)

<template> <div class="parent"> <h3>👨 父组件</h3> <p>从 Pinia 获取的 count: {{ counterStore.count }}</p> <button @click="counterStore.decrement">父亲点击 -1</button> <!-- 嵌套子组件 --> <ChildComponent /> </div> </template> <script setup> import { useCounterStore } from '@/stores/counter' import ChildComponent from './ChildComponent.vue' // 任何组件都可以直接获取同一个 store const counterStore = useCounterStore() </script>

孙子组件 (ChildComponent.vue)

<template> <div class="child"> <h4>👶 孙子组件</h4> <p>从 Pinia 获取的 count: {{ counterStore.count }}</p> <button @click="counterStore.asyncIncrement">孙子异步 +1(1秒后)</button> </div> </template> <script setup> import { useCounterStore } from '@/stores/counter' // 三层组件都能访问同一份数据! const counterStore = useCounterStore() </script>

Pinia 小结

概念

说明

Store

全局数据仓库,所有组件都能访问

State

存放数据的地方(用 ref 或 reactive)

Getters

计算属性(用 computed)

Actions

修改数据的方法(普通函数,可以是异步的)


2. Provide / Inject 依赖注入

什么是 Provide / Inject?

这是 Vue 内置的"跨层级传值"方案,不需要安装额外的库。

  • provide(提供):祖先组件提供数据
  • inject(注入):后代组件接收数据

与 Pinia 的区别:Provide/Inject 的数据是"局部的",只在当前组件树内共享;而 Pinia 是"全局的"。

基本使用

爷爷组件(提供数据)
<template> <div class="grandparent"> <h2>👴 爷爷组件 - Provide 示例</h2> <p>爷爷的消息: {{ message }}</p> <p>爷爷的主题色: {{ theme }}</p> <button @click="changeTheme">切换主题</button> <ParentProvide /> </div> </template> <script setup> import { ref, provide } from 'vue' import ParentProvide from './ParentProvide.vue' // ========== 定义要共享的数据 ========== const message = ref('来自爷爷的问候~') const theme = ref('light') // 切换主题的方法 const changeTheme = () => { theme.value = theme.value === 'light' ? 'dark' : 'light' } // ========== 使用 provide 提供数据 ========== // provide(key, value) // key: 字符串或 Symbol,用于标识 // value: 要共享的数据 // 提供普通数据 provide('message', message) // 提供响应式数据(子组件能感知变化) provide('theme', theme) // 提供方法(让子组件也能修改数据) provide('changeTheme', changeTheme) // 提供对象(包含多个相关数据) provide('userInfo', { name: '张三', age: 60, role: 'grandparent' }) </script>
父组件(中间层,不需要处理)
<template> <div class="parent"> <h3>👨 父组件</h3> <p>我是中间层,不需要 inject,数据可以跳过我直接传给孙子</p> <ChildInject /> </div> </template> <script setup> import ChildInject from './ChildInject.vue' // 注意:父组件不需要做任何事,数据会"穿透"过去 </script>
孙子组件(注入数据)
<template> <div class="child" :class="theme"> <h4>👶 孙子组件 - Inject 示例</h4> <!-- 使用注入的数据 --> <p>收到爷爷的消息: {{ message }}</p> <p>当前主题: {{ theme }}</p> <p>用户信息: {{ userInfo.name }}, {{ userInfo.age }}岁</p> <!-- 调用爷爷提供的方法 --> <button @click="changeTheme">孙子也能切换主题</button> </div> </template> <script setup> import { inject } from 'vue' // ========== 使用 inject 接收数据 ========== // inject(key) 或 inject(key, 默认值) // 接收响应式数据 const message = inject('message') const theme = inject('theme') // 接收方法 const changeTheme = inject('changeTheme') // 接收对象 const userInfo = inject('userInfo') // 设置默认值(如果祖先没有 provide,就用默认值) const notExist = inject('notExist', '这是默认值') </script> <style scoped> .light { background: #fff; color: #333; } .dark { background: #333; color: #fff; } </style>

Provide / Inject 小结

特点

说明

适用场景

跨多层组件传值,避免 props 层层传递

响应式

如果 provide 的是 ref/reactive,子组件能响应变化

作用范围

只在当前组件树内有效

与 Pinia 对比

更轻量,但没有 Pinia 的状态管理能力

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 8:02:41

Android投屏革命:QtScrcpy跨平台控制技术全面解析

Android投屏革命&#xff1a;QtScrcpy跨平台控制技术全面解析 【免费下载链接】QtScrcpy QtScrcpy 可以通过 USB / 网络连接Android设备&#xff0c;并进行显示和控制。无需root权限。 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy 还在为手机屏幕太小而…

作者头像 李华
网站建设 2026/4/2 22:13:26

特种作业操作行为智能评估系统 筑牢安全生产防线

2024年应急管理部《特种作业人员安全技术培训考核管理规定》修订版明确提出&#xff1a;“推动实操考核智能化、标准化&#xff0c;减少人为干预&#xff0c;提升评价客观性。”这一政策背后&#xff0c;是我国超3,000万特种作业人员的庞大基数&#xff0c;以及传统考核模式中“…

作者头像 李华
网站建设 2026/3/30 23:52:15

DownKyi视频下载神器:从入门到精通完全指南

DownKyi视频下载神器&#xff1a;从入门到精通完全指南 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff09;。 …

作者头像 李华
网站建设 2026/4/14 5:18:35

微信网页版访问终极解决方案:wechat-need-web插件完整使用手册

微信网页版访问终极解决方案&#xff1a;wechat-need-web插件完整使用手册 【免费下载链接】wechat-need-web 让微信网页版可用 / Allow the use of WeChat via webpage access 项目地址: https://gitcode.com/gh_mirrors/we/wechat-need-web 在数字化办公时代&#xff…

作者头像 李华
网站建设 2026/4/5 13:25:52

如何将LobeChat嵌入现有Web系统实现无缝集成?

如何将LobeChat嵌入现有Web系统实现无缝集成&#xff1f; 在企业数字化转型加速的今天&#xff0c;越来越多组织希望为员工或客户配备智能对话能力——从自动回答常见问题到辅助撰写文档、分析数据。但自研一个稳定、美观且支持多模型的聊天界面&#xff0c;往往需要投入大量前…

作者头像 李华
网站建设 2026/4/6 12:21:03

乐鑫ESP32-S3芯片深度解析:双核AI+双模无线,智能硬件开发的理想选择

当你清晨被智能闹钟的温柔铃声唤醒&#xff0c;语音指令让咖啡机自动启动&#xff0c;出门前通过手机远程检查门窗是否关好——这些习以为常的智能家居场景背后&#xff0c;都离不开一颗强大的“心脏”。在智能硬件爆发式增长的今天&#xff0c;在智能硬件飞速发展的当下&#…

作者头像 李华