目录
一、provide和inject基本介绍。
- 目的:避免 props 层层传递,实现祖先组件可向任意层级后代组件共享数据。
- 通常情况下的父子通信下:父组件向子组件传递数据,子组件内部通过props选项(setup中使用defineProps:“编译器宏”)接收。
- 关键特性。
- 祖先层级的响应式数据变更会自动同步到被注入方(被注入的层级)。
- 数据默认只读,修改需通过提供者暴露方法。也就是由注入方提供,被注入方调用提供的方法进行修改操作(保持单向数据流)。
- 核心逻辑。(跨层级传递数据基本步骤)
- 祖先组件用provide“提供”数据(响应式或非响应式)。数据可被其所有后代组件访问。
- 后代组件用inject“注入”数据。无需通过中间组件传递。
二、跨层级传递与接收数据案例实操。
(1)跨层级传递普通数据。
- 顶层组件通过provide函数提供数据。
- 底层组件通过inject函数获取数据。
- 首先搭建基本的层级组件(父->子->孙)。
- 顶层组件代码示例。
<script setup> //导入中间层组件 import Center from "./components/Center.vue"; import {provide} from "vue"; //1.跨层级传递普通数据 //2.顶层组件使用provide函数传递数据 provide('theme_color','pink') </script> <template> <div> <h1>我是顶层组件App.vue</h1> <Center></Center> </div> </template> <style scoped> </style>
- 中间层组件代码示例。
<script setup> //导入底层组件 import Bottom from "./Bottom.vue"; </script> <template> <div> <h2>我是中间层组件Center.vue</h2> <Bottom></Bottom> </div> </template> <style scoped> </style>
- 底层组件代码示例。
<script setup> import {inject} from "vue"; //2.底层组件通过inject函数接收数据 const themeColor = inject('theme_color') </script> <template> <div> <h3>我是底层组件Bottom.vue</h3>----顶层组件传递的数据:{{themeColor}} </div> </template> <style scoped> </style>
- 页面渲染效果。
(2)跨层级传递响应式数据。
- 顶层组件通过provide函数并在第二个参数设置ref对象(响应式数据)。
- 底层组件通过inject函数获取数据。
- 顶层组件代码示例。
<script setup> //导入中间层组件 import Center from "./components/Center.vue"; import {provide, ref} from "vue"; const count = ref(100) //1.跨层级传递响应式数据 //2.顶层组件使用provide函数传递数据 provide('count',count) //设置一个定时器,2秒后修改响应式count的值 setTimeout(()=>{ count.value = 500 },2000) </script> <template> <div> <h1>我是顶层组件App.vue</h1> <Center></Center> </div> </template> <style scoped> </style>
- 中间层组件代码示例。
<script setup> //导入底层组件 import Bottom from "./Bottom.vue"; </script> <template> <div> <h2>我是中间层组件Center.vue</h2> <Bottom></Bottom> </div> </template> <style scoped> </style>
- 底层组件代码示例。
<script setup> import {inject} from "vue"; //2.底层组件通过inject函数接收数据 const count = inject('count') </script> <template> <div> <h3>我是底层组件Bottom.vue</h3>----顶层组件传递的数据:{{count}} </div> </template> <style scoped> </style>
- 初始页面渲染效果。
- 设定的2s后页面渲染效果。
- 底层组件中不能随意修改顶层组件传递的响应式变量值。默认是只读状态的!
- 通常原则是:谁的数据谁维护!这时可以使用跨层级传递函数。给子孙组件提供修改响应式变量的函数即可完成修改操作!
(3)跨层级传递函数。(方便子孙组件修改传递的响应式变量)
- 顶层组件可以向底层组件传递方法。底层组件调用方法修改顶层组件中的数据!
- 顶层组件代码示例。
<script setup> //导入中间层组件 import Center from "./components/Center.vue"; import {provide, ref} from "vue"; const count = ref(100) //1.跨层级传递响应式数据 //2.顶层组件使用provide函数传递数据 provide('count',count) //3.跨层级传递函数=>给子孙组件传递可以修改响应式数据的函数 //但是控制权还是在顶层组件(可以按条件接收,也可以return等等操作) provide('changeCount',(newCount)=>{ console.log('底层组件使用函数,并传递想修改的值:', newCount) count.value = newCount }) </script> <template> <div> <h1>我是顶层组件App.vue</h1> <Center></Center> </div> </template> <style scoped> </style>
- 中间层组件代码示例。
<script setup> //导入底层组件 import Bottom from "./Bottom.vue"; </script> <template> <div> <h2>我是中间层组件Center.vue</h2> <Bottom></Bottom> </div> </template> <style scoped> </style>
- 底层组件代码示例。
<script setup> import {inject} from "vue"; //2.底层组件通过inject函数接收数据 const count = inject('count') const changeCountObj = inject('changeCount') const changeCount = () => { changeCountObj(2000) } </script> <template> <div> <h3>我是底层组件Bottom.vue</h3>----顶层组件传递的数据:{{count}} <button @click="changeCount">修改count</button> </div> </template> <style scoped> </style>
- 初始页面渲染效果。
- 点击修改count按钮后,页面渲染效果。