Vue3 依赖注入provide与inject

2024-03-19 15:12

本文主要是介绍Vue3 依赖注入provide与inject,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

        关于provide与inject下面是vue官网上的一些介绍

        通常情况下,当我们需要从父组件向子组件传递数据时,会使用props。想象一下这样的结构:有一些多层级嵌套的组件,形成了一颗巨大的组件树,而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦:

       

注意,虽然这里的 <Footer> 组件可能根本不关心这些 props,但为了使 <DeepChild> 能访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”,显然是我们希望尽量避免的情况。

provide 和 inject 可以帮助我们解决这一问题 [1]。一个父组件相对于其所有的后代组件,会作为依赖提供者。任何后代的组件树,无论层级有多深,都可以注入由父组件提供给整条链路的依赖。

一个小栗子 

        创建一个跟组件,跟组件提供了三个数据源:let message、const mesRef、const mesReactive,后两者为ref、reactive类型的值,代码如下:

<template><div class="box"><div class="show">第一层组件显示的message的值:{{ message }}</div><div class="show">第一层组件显示的mesRef的值:{{ mesRef }}</div><div class="show">第一层组件显示的mesReactive的值:{{ mesReactive }}</div><div><div>第一层组件引入第二层组件</div><midassem></midassem></div><div class="changeMsg"><div class="change" @click="changeValue('one')">change message value</div><div class="change" @click="changeValue('two')">change mesRef value</div><div class="change" @click="changeValue('three')">change mesReactive value</div></div></div>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { provide } from 'vue';
import midassem from './assembly/midassem.vue';let message = "来自第一层父组件的消息";
const mesRef = ref("来自第一层父组件的响应式消息");
const mesReactive = reactive({name: "alisa", time: "2024.3.15"});let changeNum = 0;// 使用provide在父组件中为后代组件提供数据
// 提供一个常量
provide('message', message);// 提供一个响应式常量
provide('refmsg', mesRef);// 提供一个reactive响应式对象
provide('reactivemsg', mesReactive);/* 事件回调 */
const changeValue = (tag) => {changeNum++;if (tag === "one") {message = message + "-" + changeNum;}else if(tag === "two") {mesRef.value = mesRef.value + "-" + changeNum;}else if(tag === "three"){mesReactive.value = mesReactive.value + "-" + changeNum;}
}
</script>
<style scoped lang="less">
.box {display: flex;flex-direction: column;.show {background-color: rgb(109, 144, 166);margin: 20px;padding: 20px;}.changeMsg {display: flex;flex-direction: row;margin: 20px;padding: 20px;.change {background-color: rgb(215, 146, 102);font-size: 16px;padding: 20px;margin-right: 20px;width: 380px;text-align: center;}}
}
</style>

创建一个跟组件的子组件midassem,用于展示它的一个子组件lastassem,代码如下:

<template><div class="box"><div>第二层组件,加载最后一层组件如下</div><div><lastassem></lastassem></div></div>
</template>
<script setup>
import lastassem from './lastassem.vue'
</script>
<style scoped>
.box {display: flex;flex-direction: column;
}
</style>

创建子组件lastassem,用于接收根组件provide的值,代码如下:

<template><div class="box"><div>最深层组件获取的数据:</div><div class="show">第一级组件的常量值:message = {{ message }}</div><div class="show">第一层组件的ref响应式值: refMsg = {{ refMsg }}</div><div class="show">第一层组件的reactive响应式对象:reactiveMsg = {{ reactiveMsg }}</div></div>
</template>
<script setup>
import { inject } from 'vue';// 接收第一层组件的常量值
const message = inject('message');// 接收第一层组件的ref响应式值
const refMsg = inject('refmsg');// 接收第一层组件的reactive响应式值
const reactiveMsg = inject('reactivemsg');</script>
<style scoped lang="less">
.box {display: flex;flex-direction: column;.show {background-color: aquamarine;margin: 20px;padding: 20px;}
}</style>

 看一下运行后的效果图(屏幕比较小把浏览器展示的图截成了两张):

点击下方的三个button,会分别改变根组件提供的那三个值。

青绿色的部分为子组件lastassem从根组件获取的值,值得注意的是:根组件中的ref与reactive类型的值发生改变时,子组件lastassem展示的在页面上的值也响应式的发生了改变

一些优化的技巧

        但如果你正在构建大型的应用,包含非常多的依赖提供,或者你正在编写提供给其他开发者使用的组件库,建议最好使用 Symbol 来作为注入名以避免潜在的冲突。

        我们通常推荐在一个单独的文件中导出这些注入名 Symbol,下面把上面的代码优化了一下,新建了一个symbols.js文件,专门用于存储symbol创建的key值:

/*如果你正在构建大型的应用,包含非常多的依赖提供,或者你正在编写提供给其他开发者使用的组件库,
建议最好使用 Symbol 来作为注入名以避免潜在的冲突。
*/
export const myAssemKey = Symbol();

   然后把根组件和lastassem组件的代码优化下,如下:

import { myAssemKey } from './utils/symbols.js';const mesReactive = reactive({name: "alisa", time: "2024.3.15"});// 通过Symbol作为key提供数据源
provide(myAssemKey, symbolMessage);
import { myAssemKey } from '../utils/symbols.js';// 接收第一层组件使用symbol作为key值提供的数据源
const symbolMessage = inject(myAssemKey);

        下图为展示的新的图:

这篇关于Vue3 依赖注入provide与inject的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/826397

相关文章

vite搭建vue3项目的搭建步骤

《vite搭建vue3项目的搭建步骤》本文主要介绍了vite搭建vue3项目的搭建步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1.确保Nodejs环境2.使用vite-cli工具3.进入项目安装依赖1.确保Nodejs环境

Nginx搭建前端本地预览环境的完整步骤教学

《Nginx搭建前端本地预览环境的完整步骤教学》这篇文章主要为大家详细介绍了Nginx搭建前端本地预览环境的完整步骤教学,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录项目目录结构核心配置文件:nginx.conf脚本化操作:nginx.shnpm 脚本集成总结:对前端的意义很多

前端缓存策略的自解方案全解析

《前端缓存策略的自解方案全解析》缓存从来都是前端的一个痛点,很多前端搞不清楚缓存到底是何物,:本文主要介绍前端缓存的自解方案,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、为什么“清缓存”成了技术圈的梗二、先给缓存“把个脉”:浏览器到底缓存了谁?三、设计思路:把“发版”做成“自愈”四、代码

通过React实现页面的无限滚动效果

《通过React实现页面的无限滚动效果》今天我们来聊聊无限滚动这个现代Web开发中不可或缺的技术,无论你是刷微博、逛知乎还是看脚本,无限滚动都已经渗透到我们日常的浏览体验中,那么,如何优雅地实现它呢?... 目录1. 早期的解决方案2. 交叉观察者:IntersectionObserver2.1 Inter

Vue3视频播放组件 vue3-video-play使用方式

《Vue3视频播放组件vue3-video-play使用方式》vue3-video-play是Vue3的视频播放组件,基于原生video标签开发,支持MP4和HLS流,提供全局/局部引入方式,可监听... 目录一、安装二、全局引入三、局部引入四、基本使用五、事件监听六、播放 HLS 流七、更多功能总结在 v

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni