vue3 中的依赖注入「建议收藏」

vue3 中的依赖注入「建议收藏」1.前言 依赖注入,一个近年来非常流行的一种思想,号称是解耦的大杀器。所以,像angular这种顶级的老大哥,一早实现了比较完整的依赖注入,并有着和.net core,spring类似的构造函数注入(

1.前言

依赖注入,一个近年来非常流行的一种思想,号称是解耦的大杀器。所以,像angular这种顶级的老大哥,一早实现了比较完整的依赖注入,并有着和.net core,spring类似的构造函数注入(constructor injection)这种丝滑的使用方式,可以说是能够很大程度上代替全局状态管理的存在:

image.png

当然,在vue上,也慢慢实现了依赖注入(provide,inject),并在vue3.0中得到了进一步完善:

image.png

当然它的实现方式,其实个人认为和reactcontext比较像。

2. 基础使用

为了紧跟typesciprtvue3.0的潮流,这里仅展示在setup中的基础使用,实现一个经典的count:

2.1 parent.vue

<template>
 <child></child>
 <button @click="count++">+1</button>
</template>

<script lang="ts">
import { defineComponent,inject,provide,ref,Ref } from "vue";
import Child from "./child.vue";

export const  PROVIDE_TOKEN = "PROVIDE_TOKEN";
export type TParentProvide = {
     count:Ref<number>
}
 export default defineComponent({
       components:{
           Child
       },
       setup(){
           const count = ref(0);
           provide<TParentProvide>(PROVIDE_TOKEN,{count})

           return  {
               count
           }
       }
 })
</script>

2.2 child.vue

<template>
<p>{{title}}</p>
</template>

<script lang="ts"> import { defineComponent,inject,provide } from "vue"; import { PROVIDE_TOKEN, TParentProvide } from "./parent.vue"; export default defineComponent({ setup(){ const provide = inject<TParentProvide>(PROVIDE_TOKEN); return { title : provide?.count } } }) </script> 

2.3 效果

image.png

3.结论 & 注意点

3.1 注意点

可以看到上例简单的实现了一个依赖注入,当然这里有几个注意点:

1.只能用在父子级别,同级的不能使用

这个还是比较好理解的,和reactcontext表现一致。

2.inject/provide只能在setup运行期间使用

inject/provide只能在setup运行期间使用,这是比较关键的一个点,和hook不能在条件判断中使用有点类似,不过inject/provide还能在生命周期中使用。看下例子,这次我们在click事件中尝试使用inject获取依赖:

<template>
 <p>{{title}}</p>
 <button @click="add">+1</button>
</template>

<script lang="ts">
import { computed, defineComponent,inject } from "vue";
import { PROVIDE_TOKEN, TParentProvide } from "./parent.vue";


 export default defineComponent({
       setup(){
          const title = computed(()=>{
              return inject<TParentProvide>(PROVIDE_TOKEN)!.count.value
          });

         function add(){
             console.log(inject<TParentProvide>(PROVIDE_TOKEN));
             inject<TParentProvide>(PROVIDE_TOKEN)!.count.value =  inject<TParentProvide>(PROVIDE_TOKEN)!.count.value + 1;

         }

          return {
              title ,
              add
          }
       }
 })
</script>

打开控制台并点击按钮

image.png

可以看到打印出了错误,并有提示提示翻译成大白话就是:”inject() 只能用在setup() 或者函数组件中”。所以当我们使用vue-router等第三方插件提供的获取实例的函数(例如vue-router的useRoute)时,需要注意这一点,因为例如useRoute等函数的实现也是基于inject/provide的。

3.2 结论

所以我选angular

v2-0390caf041fab4013c2270f9d4fbb8af_720w.jpg

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12876.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注