【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. 一个组件体系 下,多层级多个组件使用的时候
相关推荐
Daniel李华5 小时前
echarts使用案例
android·javascript·echarts
北原_春希5 小时前
如何在Vue3项目中引入并使用Echarts图表
前端·javascript·echarts
JY-HPS5 小时前
echarts天气折线图
javascript·vue.js·echarts
尽意啊5 小时前
echarts树图动态添加子节点
前端·javascript·echarts
吃面必吃蒜5 小时前
echarts 极坐标柱状图 如何定义柱子颜色
前端·javascript·echarts
O_oStayPositive5 小时前
Vue3使用ECharts
前端·javascript·echarts
竹秋…5 小时前
echarts自定义tooltip中的内容
前端·javascript·echarts
宝贝露.5 小时前
Axure引入Echarts图无法正常显示问题
前端·javascript·echarts
人良爱编程5 小时前
Hugo的Stack主题配置记录03-背景虚化-导航栏-Apache ECharts创建地图
前端·javascript·apache·echarts·css3·html5
来颗仙人掌吃吃5 小时前
解决Echarts设置宽度为100%发现宽度变为100px的问题(Echarts图标宽度自适应问题)
前端·javascript·echarts