【Vue.js】provide & inject

前言:

前端项目的特点:

当前我们开发的前端项目都是以视图作为划分单位,将不同区域的视图显示划分成了许许多多的【碎片】。

组件化就是一种流行,高效,易维护的视图划分模式。

从组件化说起:

组件化 就是将视图划分成易维护可复用职责单一的视图碎片。

在项目中,这些碎片组成了我们项目需要的样子和功能,并最终组合成一个页面交互的整体(组件树)

在 Vue 组件的数据传递中,通常使用 props 这种标准化传递方式来进行数据传递。

模拟场景:

假定有一个这样的场景:

  1. 组件树上面有两个组件:组件 A、组件 B
  2. 组件 A 的可配置性很高,数据来源都是外界提供的
  3. 组件 B 的复用性很高,可以在任意组件之中渲染

从原则上来讲,组件 A 和组件 B 之间是可以相互依赖共用的。但是:

  1. 当组件树变得越来越复杂,它们需要嵌套和复用的次数越来越多(组合 & 嵌套),就会有可能产生许多层组件并未使用的数据出现的问题
  2. 当组件使用多次时,数据来源追踪困难
  3. 通常情况下,每次使用组件,都需要进行注册并且注册完成就要思考嵌套的数据来源

补充 - 组件设计的一些注意点:

  1. 组件依赖关系要简单
  2. 组件的嵌套不能太深(组件设计需要扁平化)

虽然 props 是组件数据传递的标准方式,但是上述的业务场景可能会导致标准的数据传递方式使用起来不太灵光

这个时候,我们就需要使用 provide & inject (依赖注入) 的方式来解决我们在组件数据传递的标准方式不太使用的情景。

Provide & Inject

概述:

Provide & Inject是 Vue 官方提出的祖先组件派发数据给后代组件的非标准数据传递方式,具体步骤如下:

  1. 祖先组件使用 provide 提供数据(状态 & 方法)
  2. 后代组件调用 inject 接收组建组件传递的数据

代码示例:

基本使用

  1. 祖先定义
html 复制代码
<template>
  <Child />
</template>

<script>
  import { defineComponent } from 'vue';

  import Child from './Child.vue';
  
  export default defineComponent({
    name: 'Ancient',
    components: {
      Child
    },
    provide() {
      return {
        msg: 'hello my child'
      };
    }
  });
</script>
  1. 后代获取
html 复制代码
<template>
  <div>
    <h2>{{ msg }}</h2>
  </div>
</template>

<script>
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'Child',
    inject: ['msg']
  });
</script>

补充:定义响应式数据

  • provide 和 inject 默认传递的数据不是响应式的 (不被代理 / 数据劫持)
  • 在 Vue3 中,如果在 options API 需要传递响应式数据,需要使用 Vue.computed 包裹数据!
  • 在 Vue2 中,只能传递响应式对象来维持数据的深度响应!

传递方法

  1. 祖先定义
html 复制代码
<template>
  <Child />
</template>

<script>
  import { defineComponent } from 'vue';

  import Child from './Child.vue';
  
  export default defineComponent({
    name: 'Ancient',
    components: {
      Child
    },
    provide() {
      const { print } = this;
      return {
        msg: 'hello my child',
        print
      };
    },
    methods: {
      print(msg) {
        console.log(msg);
        return this.print.bind(this);
      }
    },
  });
</script>
  1. 后代获取
html 复制代码
<template>
  <div>
    <h2 @click="print('hahaha')">{{ msg }}</h2>
  </div>
</template>

<script>
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'Child',
    inject: ['msg', 'print']
  });
</script>

总结 - 什么场景下适合使用 Provide & Inject 呢?

  1. 一个组件体系 下,如果有深度嵌套
  2. 一个组件体系 下,多层级多个组件使用的时候
相关推荐
森叶38 分钟前
Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
前端·javascript·electron
霸王蟹1 小时前
React 19 中的useRef得到了进一步加强。
前端·javascript·笔记·学习·react.js·ts
霸王蟹1 小时前
React 19版本refs也支持清理函数了。
前端·javascript·笔记·react.js·前端框架·ts
繁依Fanyi1 小时前
ColorAid —— 一个面向设计师的色盲模拟工具开发记
开发语言·前端·vue.js·编辑器·codebuddy首席试玩官
codelxy1 小时前
vue引用cesium,解决“Not allowed to load local resource”报错
javascript·vue.js
程序猿阿伟2 小时前
《社交应用动态表情:RN与Flutter实战解码》
javascript·flutter·react native
明似水2 小时前
Flutter 开发入门:从一个简单的计数器应用开始
前端·javascript·flutter
沐土Arvin2 小时前
前端图片上传组件实战:从动态销毁Input到全屏预览的全功能实现
开发语言·前端·javascript
Zww08913 小时前
el-dialog鼠标在遮罩层松开会意外关闭,教程图文并茂
javascript·vue.js·计算机外设
sunbyte3 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | 页面布局 与 Vue Router 路由配置
前端·javascript·vue.js·tailwindcss