vueinject的简单介绍

本篇文章给大家谈谈vueinject,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Vue的依赖注入简单介绍

我们在使用vue写项目的时候,偶尔会遇到毕裂野这种情况:

组件A里面嵌套了组件B,组件B里面又嵌套了组件C,然后由于业务需要,我们需要在组件C里面访问组件A的数据或者方法。

我们的处理办法一般是:

但是这些方法总是不够高效,没内味。

针对这种组件嵌套的问题,Vue提供了一个解决方案——依赖注入[provide/inject],由父组件定义一个可供全部后代组件访问的方法或者变量,子组件在组件内声明好需要使用的属性或者方法后即可直接调用。

虽然这里叫依赖注入,但是跟大部分人认知的Class的依赖注入还是有点区别的,这里更多的是指建立一个上下文关系,不过主要的思想还是

在A组件处通过provide属性,提供需要给后代使用手喊的方法,C组件在inject处声明好自己需要的方法名,然后直接调用,通过源丛依赖注入的方式实现跨层级方法的调用

vue-依赖注入

Vue3全局组件通信之provide / inject

顾名思义,爷孙组件是比 父子组件通信 要更深层次的引用关系(也有称之为 “隔代组件”):

C组件引入到B组件里,B组件引入到A组件里渲染,此时A是C的爷爷级别(可能还有更多层级关系),如果你用 props ,只能一级一级传递下去,那就太繁琐了,因此我们需要更直接的通信方式。

他们之间的关系如下, Grandson.vue 并非直接挂载在 Grandfather.vue 下面,他们之间还隔着至少一个 Son.vue (可能有多个):

这一 Part 就是讲一讲 C 和 A 之间的数据传递,常用的方法有:

为了方便阅读,下面的父组件统一叫 Grandfather.vue ,子组件统一叫 Grandson.vue ,但实际上他们之间可以隔无数代…

TIP

因为上下级的关系的一致性,爷孙组件通信的方案也适用于 父子组件通信 ,只需要把爷孙关系换成父子关系即可。

这个特性有两个部分: Grandfather.vue 有一个 provide 选项来提供数据, Grandson.vue 有一个 inject 选项来开始使用这些数据。

无论组件层次结构有多深,发起 provide 的组件都可以作为其所有下级组件的依赖提供者。

TIP

这扮轿档一部分的内容变化都特别大,但使用起来其实也很简单,不用慌,也有相同的地方:

另外,要切记一点就是:provide 和 inject 绑定并不是可响应的。这是刻意为之的,但如果传入了一个可监听的对象,那么其对象的 property 还是可响应的。

我们先来回顾一下 2.x 的用法:

旧版的 provide 用法和 data 类似,都是配置为一个返回对象的函数。

3.x 的新版 provide , 和 2.x 的用法区别比较大。

TIP

在 3.x , provide 需要导入并在 setup 里启用,并且现在是一个全新的方法。

每次要 provide 一个数据的时候,就要单独调用一次。

每次调用的时候,都需要传入 2 个参数:

来看一下如何创建一个 provide :

操作非常简单对吧哈哈哈,但需要注意的是, provide 不是响应式的,如果你要使其具备响应性,你需要传入响应式数据,详见: 响应性数据的传递与接收

也是先来回顾一下 2.x 的用法:

旧版的 inject 用法和 props 类似,3.x 的新版 inject , 和 2.x 的用法区别也是比较大。

TIP

在 3.x, inject 和 provide 一样,也是需要先导入然后在 setup 里启用,也是一个全新的方法。

每次要 inject 一个数据的时候,厅乱就要单独调用一次。

每次调用的时候,只需要传入 1 个参数:

来看一下如何创建一个 inject :

也是很简单(写 TS 的话,由于 inject 到的值可能是 undefined ,所以要么加个 undefined 类型,要么给变量设置一个空的默认值)。

之所以要单独拿出来说, 是因为变化真的很大 - -

在前面我们已经知道,provide 和 inject 本身不可响应,但是并非完全不能够拿到响应的结果,只需要我们传入的数据具备响应性,它依然能够提供响应支持。

我们以 ref 和 reactive 为例,来看看应该怎么发起 provide 和接收 inject 。

对这 2 个 API 还不熟悉的同学,建议先阅读一下 响应式 API 之 ref 和 响应式 API 之 reactive 。

先在 Grandfather.vue 里 provide 数据:

在帆迅 Grandsun.vue 里 inject 拿到数据:

非常简单,非常方便!!!

TIP

响应式的数据 provide 出去,在子孙组件拿到的也是响应式的,并且可以如同自身定义的响应式变量一样,直接 return 给 template 使用,一旦数据有变化,视图也会立即更新。

但上面这句话有效的前提是,不破坏数据的响应性,比如 ref 变量,你需要完整的传入,而不能只传入它的 value ,对于 reactive 也是同理,不能直接解构去破坏原本的响应性。

切记!切记!!!

provide 和 inject 并不是可响应的,这是官方的故意设计,但是由于引用类型的特殊性,在子孙组件拿到了数据之后,他们的属性还是可以正常的响应变化。

先在 Grandfather.vue 里 provide 数据:

在 Grandsun.vue 里 inject 拿到数据:

引用类型的数据,拿到后可以直接用,属性的值更新后,子孙组件也会被更新。

基本数据类型被直接 provide 出去后,再怎么修改,都无法更新下去,子孙组件拿到的永远是第一次的那个值。

先在 Grandfather.vue 里 provide 数据:

在 Grandsun.vue 里 inject 拿到数据:

很失望,并没有变化。

TIP

那么是否一定要定义成响应式数据或者引用类型数据呢?

当然不是,我们在 provide 的时候,也可以稍作修改,让它能够同步更新下去。

我们再来一次,依然是先在 Grandfather.vue 里 provide 数据:

再来 Grandsun.vue 里修改一下 inject 的方式,看看这次拿到的数据:

这次可以正确拿到数据了,看出这2次的写法有什么区别了吗?

TIP

基本数据类型,需要 provide 一个函数,将其 return 出去给子孙组件用,这样子孙组件每次拿到的数据才会是新的。

但由于不具备响应性,所以子孙组件每次都需要重新通过执行 inject 得到的函数才能拿到最新的数据。

按我个人习惯来说,使用起来挺别扭的,能不用就不用……

点赞加关注,永远不迷路

vue组件隔代传值 provide / inject

一般在层级不多的组件中,我们都是用props去和子组件通信,但是如果层级比较多了,props用起来就显得不是那么灵活了。这个时候要么用订阅发布消息,要么用vuex来解决传值的问题。而vue官方也同时推出了一组api: provide / inject 用来隔代传值。

provide/inject 需要一起使用,我们可以从父组件的provide传值,子组件或者孙组件,就可以用inject来接受子组件的provide属性值

具体使用方法如下

首先在父组件中注入provide

子孙组件接收

这样就完成了基本使用。可以把provide想象成一个容器,他去把需要多层传递的data里的属性都收集起来,并且重新给个key。然后子组件里可以通过inject来接收这些属性,inject的值是一个数组,里面放上需要接收的属性的key就可以了。

当然,这样传递的数据并不是响应式的,文档尘告枝中已经说明。如果想要响应式那provide传递的值就得是个响应式对象,比如这样

父组件这样注入,子组件就会接收到一个可响应的数据了。

传值解决了,那此时子组件该如何跟父组件通信呢。大家都知道,子组件是不可以修改父组件的数据了。vue为了保证数据的可维护性,是不提倡子组件去修改父组件的数据的。所以一般我们都是在父组件里写个方法,然后将此方法传递给子组件,子组件通过$emit来友此调用这个方法,以派敏达到修改数据的目的。

那么在provide / inject应该怎么做呢?

其实也很简单,我们同样可以在provide中注入一个方法,提供给子组件修改数据。子组件只需要接收,调用就醒了。

[img]

VUE3.0 provide/inject的异步传递问题

解决vue3.0中 provide/inject的异步传递问题

备注:provide/inject都必须在setup中使用

1. 同步使用

    祖先组件

    import { ref, provide } from 'vue'

    export default {

      setup() {

           const msg = ref('')

            provide('msg', msg)

        }

    }

    孙子辈组件谈扰

    import { inject } from 'vue'

    export default {

      setup() {

         const msg = inject ('msg')

          return { msg }

   含乎     }

    }

2. 异步使用

祖先组件

import { ref, provide } from 'vue'

    export default {

      setup() {

            // 逻辑就是先发射出去,然后再异步中改变值,这样祖孙组件就可以接收到了

            const msg = ref('')

            provide('msg', msg)

            // 异步处理

            setTimeout(() = {

         谈侍悉         msg.value = '收到一条消息';

             }, 3000)

        }

    }

孙子辈组件

import { inject } from 'vue'

export default {

   setup() {

        const msg = inject ('msg')

        return { msg }

    }

  }

关于vueinject和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表