vue3 provide与inject 。vue3 跨越组件传递参数,传参。父子组件传值,爷孙组件传参。跨层级传值,整个组件树中共享传值 电脑版发表于:2024/8/20 22:41 在 Vue 3 中,provide 和 inject 是用于实现跨组件通信的 API,特别是当组件层次结构较深时很有用,不然如果层级太深了要一级一级的往下传比较麻烦,用provide 和inject,可以在整个组件树中共享。 [TOC] ### 基础使用 #### 父组件 父组件赋值之后可以在整个组件树中都获取到值,后代子组件都能获取到值 ``` <script lang="ts" setup> import { reactive,provide } from 'vue' const provideData = reactive({ stid: "", schoolId:"", schoolName:"" }) provide('schoolInfo', provideData); </script> ``` #### 子组件,或者说是后代组件中 ``` <script lang="ts" setup> import { inject } from 'vue' const schoolInfo:any = inject('schoolInfo'); </script> ``` ### 注意,要想子组件监听到变化,应该监听响应式对象的引用,而不是一个值,特别是想要提供的值是异步方法调用之后提供的 #### 这样提供的值子组件获取不到 因为state虽然是响应式对象,但是state.userList不是,所以子组件获取到的值只是初始化的空值 ``` const state = reactive({ ......其他字段 userList:[] }); provide('userList', state.userList); onMounted(() => { getUserList() }); const getUserList = async()=>{ const result: any = await request.get('/xx/api/useraccount/GetUserListByTenantID'); state.userList = result.data } ``` #### 这样监听响应式对象的引用是可以的 ``` const userListRef = reactive({ value: [] }); provide('userList', userListRef); onMounted(() => { getUserList() }); const getUserList = async()=>{ const result: any = await request.get('/xx/api/useraccount/GetUserListByTenantID'); userListRef.value = result.data } ``` 在第二种方法中,创建了一个响应式对象 userListRef,它有一个 value 属性,初始值为空数组。然后,你在 setup 函数中调用了 provide('userList', userListRef),将 userListRef 提供给子组件。由于 userListRef 是一个响应式对象,并且提供的是这个对象的引用,所以当 userListRef.value 被更新时,所有通过 inject 获取到 userListRef 的子组件都会接收到更新后的引用,并且可以访问到新的 value。 #### 总结一下 tn2>当使用 provide 和 inject 时,你应该提供响应式对象的引用,而不是对象的直接属性(如数组或对象内部的字段)。这是因为 Vue 的响应式系统是基于引用追踪的,而不是基于值比较的。当你提供一个对象的引用时,Vue 能够追踪到这个对象的变化,并通知所有依赖这个对象的子组件。而当你直接提供一个属性(如数组)时,Vue 无法追踪到这个属性的变化(除非这个属性本身是一个响应式引用)。 因此,在你的情况下,你应该继续使用第二种方法,即通过提供一个响应式对象的引用来使用 provide 和 inject。 #### 注意不能直接在异步请求里边使用provide 比如这种写法: ``` const getUserList = async()=>{ const result: any = await request.get('/xx/api/useraccount/GetUserListByTenantID'); // 不能在请求里边直接使用provide,子组件获取不到这个接口返回的值 provide('userList',result.data); } ``` 在 Vue 3 的 Composition API 中,你不能在异步函数(如 API 请求回调)内部直接调用 provide 并期望它立即对已经渲染的子组件生效。provide 是在组件的 setup 函数中调用的,它设置了当前组件提供的依赖项,这些依赖项对于在 setup 函数执行期间或之后创建的子组件是可见的。 当你在异步函数(如 getUserList)中调用 provide 时,如果这个函数是在 setup 函数之外或之后调用的,那么它提供的值可能不会被已经渲染的子组件所接收。这是因为子组件的 setup 函数和渲染过程可能已经在父组件的 setup 函数执行完毕并且 provide 被调用之前就完成了。