【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. 一个组件体系 下,多层级多个组件使用的时候
相关推荐
萌萌哒草头将军2 小时前
🚀🚀🚀React Router 现在支持 SRC 了!!!
javascript·react.js·preact
90后的晨仔4 小时前
Vue Router 入门指南:从零开始实现前端路由管理
前端·vue.js
90后的晨仔4 小时前
零基础快速搭建 Vue 3 开发环境(附官方推荐方法)
前端·vue.js
孤独的根号_4 小时前
Vite背后的技术原理🚀:为什么选择Vite作为你的前端构建工具💥
前端·vue.js·vite
拾光拾趣录6 小时前
Element Plus表格表头动态刷新难题:零闪动更新方案
前端·vue.js·element
Adolf_19937 小时前
React 中 props 的最常用用法精选+useContext
前端·javascript·react.js
前端小趴菜057 小时前
react - 根据路由生成菜单
前端·javascript·react.js
喝拿铁写前端7 小时前
`reduce` 究竟要不要用?到底什么时候才“值得”用?
前端·javascript·面试
空の鱼7 小时前
js与vue基础学习
javascript·vue.js·学习
鱼樱前端7 小时前
2025前端SSR框架之十分钟快速上手Nuxt3搭建项目
前端·vue.js