Vue3中的provide、inject怎么使用
一. 场景再现
先别着急考虑标题这个 api 的含义。在这里我先动手写一个比较常见的场景。
所对应的组件内部代码比较简单,这里我就不展示了,逻辑上就是 这三个组件层层引用。
所对应的页面效果如下:
如上图,这是一个在项目中很常见的一个场景,三层嵌套的组件。(其实还有深层次的嵌套,目前我们拿三层嵌套举例足矣)
ok,你现在的需求是:在爷爷组件内需要提供一个字符串数据 “韩振方” 去提供给 儿子组件使用。
聪明的你肯定想到了 props,废话不多说,我们直接上手。
二. 传递 Props
“我以为多高深呢,这不就是数据父传子的场景吗?我直接传递 props 去完成这个需求。”
于是我会在 GrandFather.vue
写下这样一段代码
接下来就该去 Father.vue
组件去接收这个数据了。于是我们在 Father.vue
组件定义了 props
去接收这个值。
我们看一眼页面
没什么问题,爸爸组件已经收到了。但是别忘了我们任务还没完成呢,我们的需求是给儿子组件使用,
于是我们又赶紧接着往下传递。
所以现在我们的 Children.vue
组件的样子就变成这个样子。
页面效果如下:
最终我们的 儿子组件 也确实拿到了。
写到这里你发现了一些不太对劲的地方吗?????
其实我们的爸爸组件是完全不需要知道这些属性的,它仅仅只是充当了一个传话筒。如果这个组件单纯是这一个使用场景还好,但是一旦我们想要在第二个地方复用爸爸组件的时候,我们会发现问题就来了。我们必须给这个爸爸组件提供一个叫做 message1
的 props
,但是实际上这个 message1
并不是一个爸爸组件内部自己使用的一个属性。
写到这里你发现了,仅仅只多传递了一层,就导致组件的复用性变得很差。这还是仅仅只嵌套了三层的场景,一旦到了第四层,你会发现事情逐渐开始变得棘手起来了,好像 props
并不是一个好的选择了。
想到这里你会开始思考,有没有更好的解决方法呢?你别说,还真有,那就是我们今天的主角,provide
和 inject
。
三. provide 和 inject
首先不要死记硬背 api 的名字,作者起名字肯定都是有原因的。在很多情况下我们通过先看这两个单词的意思。
单从这两个单词的含义就大概能猜出个大概的意思,一个是提供某个值,另一个是去注册,接收这个值。
那么问题就引出来了,我们怎么正确的使用这两个 api 呢?其实很简单,让我们回到爷爷组件,还原他最初的模样。
你做的仅仅只需要两步:
或许你会惊讶,就这样就行了?我明确告诉你,是的,这样就行了。
接下来最后一步,去儿子组件接收使用就大功告成了。
我们看一下页面效果:
不仅仅数据成功拿到了,而且关键的是我们的爸爸组件是干干净净的,丝毫不影响其他地方对它的引用。
我们再回过头讲解 provide 的用法。provide 接受两个参数。第一个参数需要是一个独一无二的标识(不允许和组件内部的变量重名),第二个参数就是准备传递的值。
你也可以这样理解,现在爷爷组件拿着一个喇叭在喊????:“谁要‘韩振方’,谁要‘韩振方’,价格便宜,仅仅需要一个‘message’”。
这时候儿子组件听到了这个消息,大喊:“我要我要!!”于是它就赶紧 inject 了一个 “message”。
注意: 你用于接受的变量名字是随便起的,不需要你和前面保持一致。
而爸爸组件丝毫不想要,所以它就压根不需要 inject。
并且 inject 还可以允许你有个兜底的行为。什么意思? 假设这个儿子组件在别的地方也需要复用,但是它的爷爷组件或者它压根就没有爷爷组件,那么第二个参数将作为 suibian
的默认值。
我们测试一下,我们首先取消了爷爷组件的 provide 行为。
可以看到,页面正确的显示了我们的兜底数据。
四. provide 的进阶用法
provide 的作用远远不止提供字符串类型数据而已,我们在爷爷组件声明一个响应式的数据试试。
现在儿子组件长大了,它说我自己也想控制数字的增长,可以吗?爷爷组件是很宠孙子的,于是又提供了一个方法给孙子使用。
儿子组件真的可以自己控制吗?孩子真的长大了吗?
可以看到儿子组件确实是长大了(指成功 inject 了爷爷组件 provide 的函数)
千万不要转头就忘,第二个参数是我们的兜底行为。如果爷爷没提供函数,我就自己使用一个没有任何行为的箭头函数。仅此而已。
五. 源码
爷爷组件代码
<script lang="ts" setup> // 这是爷爷组件 import { ref } from "vue"; import { provide } from "vue"; import Father from "./Father.vue"; const count = ref<number>(0); function add() { count.value = count.value + 1; } provide("message", count); provide("messageAdd", add); //我把 add 也同时提供给儿子组件 </script> <template> <div class="w-full h-[300px] bg-[black]"> <span class="text-white text-[20px]">爷爷组件</span> <button @click="add">message+1</button> <Father /> </div> </template>
父亲组件代码
<script lang="ts" setup> // 这是父亲组件 import Children from "./Children.vue"; </script> <template> <div class="w-[70%] h-[270px] bg-[pink]"> <span class="text-[black] text-[20px]">爸爸组件</span> <span class="text-[black] text-[15px]"></span> <Children /> </div> </template>
儿子组件代码
<script lang="ts" setup> // 这是儿子组件 import { inject } from "vue"; const suibian = inject("message", "假如爷爷没提供没有的话就用我"); const add = inject("messageAdd", () => {}); </script> <template> <div class="w-[70%] h-[230px] bg-[white]"> <span class="text-[black] text-[20px]">儿子组件</span> <span class="text-[black] text-[10px]">{{ suibian }}</span> <button @click="add">长大了,我自己+1</button> </div> </template>
六. 思考题
如果我现在爷爷组件和父亲组件同时提供了一个相同的关键词的值,儿子组件最后会使用谁的呢?
GrandFather.vue: => provide("message","爷爷组件提供的");
Father.vue: =>provide("message","父亲组件提供的")
Children.vue:=> inject("message","我使用谁的?")
以上是Vue3中的provide、inject怎么使用的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

vue3+vite:src使用require动态导入图片报错和解决方法vue3+vite动态的导入多张图片vue3如果使用的是typescript开发,就会出现require引入图片报错,requireisnotdefined不能像使用vue2这样imgUrl:require(’…/assets/test.png’)导入,是因为typescript不支持require所以用import导入,下面介绍如何解决:使用awaitimport

tinymce是一个功能齐全的富文本编辑器插件,但在vue中引入tinymce并不像别的Vue富文本插件一样那么顺利,tinymce本身并不适配Vue,还需要引入@tinymce/tinymce-vue,并且它是国外的富文本插件,没有通过中文版本,需要在其官网下载翻译包(可能需要翻墙)。1、安装相关依赖npminstalltinymce-Snpminstall@tinymce/tinymce-vue-S2、下载中文包3.引入皮肤和汉化包在项目public文件夹下新建tinymce文件夹,将下载的

想要实现页面的局部刷新,我们只需要实现局部组件(dom)的重新渲染。在Vue中,想要实现这一效果最简便的方式方法就是使用v-if指令。在Vue2中我们除了使用v-if指令让局部dom的重新渲染,也可以新建一个空白组件,需要刷新局部页面时跳转至这个空白组件页面,然后在空白组件内的beforeRouteEnter守卫中又跳转回原来的页面。如下图所示,如何在Vue3.X中实现点击刷新按钮实现红框范围内的dom重新加载,并展示对应的加载状态。由于Vue3.X中scriptsetup语法中组件内守卫只有o

Vue实现博客前端,需要实现markdown的解析,如果有代码则需要实现代码的高亮。Vue的markdown解析库有很多,如markdown-it、vue-markdown-loader、marked、vue-markdown等。这些库都大同小异。这里选用的是marked,代码高亮的库选用的是highlight.js。具体实现步骤如下:一、安装依赖库在vue项目下打开命令窗口,并输入以下命令npminstallmarked-save//marked用于将markdown转换成htmlnpmins

最终效果安装VueCropper组件yarnaddvue-cropper@next上面的安装值针对Vue3的,如果时Vue2或者想使用其他的方式引用,请访问它的npm官方地址:官方教程。在组件中引用使用时也很简单,只需要引入对应的组件和它的样式文件,我这里没有在全局引用,只在我的组件文件中引入import{userInfoByRequest}from'../js/api'import{VueCropper}from'vue-cropper&

前言无论是vue还是react,当遇到多处重复代码的时候,我们都会想着如何复用这些代码,而不是一个文件里充斥着一堆冗余代码。实际上,vue和react都可以通过抽组件的方式来达到复用,但如果遇到一些很小的代码片段,你又不想抽到另外一个文件的情况下,相比而言,react可以在相同文件里面声明对应的小组件,或者通过renderfunction来实现,如:constDemo:FC=({msg})=>{returndemomsgis{msg}}constApp:FC=()=>{return(

vue3+ts+axios+pinia实现无感刷新1.先在项目中下载aiXos和pinianpmipinia--savenpminstallaxios--save2.封装axios请求-----下载js-cookienpmiJS-cookie-s//引入aixosimporttype{AxiosRequestConfig,AxiosResponse}from"axios";importaxiosfrom'axios';import{ElMess

使用Vue构建自定义元素WebComponents是一组web原生API的统称,允许开发者创建可复用的自定义元素(customelements)。自定义元素的主要好处是,它们可以在使用任何框架,甚至是在不使用框架的场景下使用。当你面向的最终用户可能使用了不同的前端技术栈,或是当你希望将最终的应用与它使用的组件实现细节解耦时,它们会是理想的选择。Vue和WebComponents是互补的技术,Vue为使用和创建自定义元素提供了出色的支持。你可以将自定义元素集成到现有的Vue应用中,或使用Vue来构
