【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. 一个组件体系 下,多层级多个组件使用的时候
相关推荐
JohnYan44 分钟前
工作笔记 - CentOS7环境运行Bun应用
javascript·后端·容器
东风西巷3 小时前
Rubick:基于Electron的开源桌面效率工具箱
前端·javascript·electron·软件需求
Miracle_G3 小时前
每日一个知识点:JavaScript 箭头函数与普通函数比较
javascript
unfetteredman3 小时前
Error: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found
前端·javascript·vite
HANK4 小时前
KLineChart 绘制教程
前端·vue.js
程序员小续5 小时前
React 官方严令禁止:Hook 不能写在 if/else,真相竟然是…
前端·javascript·程序员
Juchecar5 小时前
Naive UI 学习指南 - Vue3 初学者完全教程
前端·vue.js
小奋斗5 小时前
深入浅出:JavaScript中 三大异步编程方案以及应用
javascript·面试
尝尝你的优乐美5 小时前
封装那些Vue3.0中好用的指令
前端·javascript·vue.js
敲代码的彭于晏5 小时前
localStorage 不够用?试试 IndexedDB !
前端·javascript·浏览器