vue 依赖注入使用教程

news2024/9/24 1:20:40

vue 中的依赖注入,官网文档已经非常详细,笔者在这里总结一份

目录

1、背景介绍

2、代码实现

2.1、依赖注入固定值

2.2、 依赖注入响应式数据

3、注入别名

4、注入默认值

5、应用层 Provide

6、使用 Symbol 作注入名


1、背景介绍

为什么会出现依赖注入呢?其实它是要解决 Prop 逐级透传问题

Prop 逐级透传问题,即通常情况下,当我们需要从父组件向子组件传递数据时,会使用 props,如果只是父传子,这样层级不深的结构,是比较简单的;如果是层级非常深,祖太爷、太爷、爷、父、子、孙、重孙组件......,这样多层级嵌套的组件,形成了一颗巨大的组件树,此时,如果重孙组件需要祖太爷组件中的部分数据,在这种情况下,如果仅使用 props 则必须将其沿着组件链逐级传递下去,这会非常麻烦。而且中间的爷、父等组件可能根本不关心这些 props,为了使重孙组件能够访问到它们,仍然需要定义并向下传递。如果组件链路非常长,可能会影响到更多这条路上的组件。这一问题被称为“prop 逐级透传”

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

下图摘自vue官网

 

2、代码实现

下面代码实现依赖注入

新建vue项目,这里笔者定义3个组件。图书馆组件Library(爷),图书组件Book(父)、标题组件Title(孙),实现图书馆组件Library(爷)提供数据,标题组件Title(孙)注入使用

项目结构

 

2.1、依赖注入固定值

图书馆组件Library(爷)提供 bookName

<template>
    <div>
        <h1>图书馆</h1>
        <Book/>
    </div>
</template>
<script>
import Book from './Book.vue'
export default {
    components: {
        Book
    },
    provide: {
        bookName: '三国演义'
    },
}
</script>

图书组件Book(父)

<template>
    <div>
        <h2>书名</h2>
        <Title />
    </div>
</template>
<script>
import Title from './Title.vue'
export default {
   components: {
    Title
   }
}
</script>

标题组件Title(孙),注入bookName 

<template>
    <div>
        <p>标题</p>
        <p>{{bookName}}</p>
    </div>
</template>
<script>
export default {
    inject: ['bookName'],
}
</script>

App.vue,引入图书馆组件Library

<template>
  <Library />
</template>

<script>
import Library from './components/Library.vue'

export default {
  name: 'App',
  components: {
    Library
  }
}
</script>

运行效果

2.2、 依赖注入响应式数据

上例2.1依赖注入的 bookName 是个固定的值,本例将 bookName 改成响应式数据

图书组件Book(父)和标题组件Title(孙)不需要改,只改图书馆组件Library(爷)即可

图书馆组件Library(爷)

为保证注入方和供给方之间的响应性链接,需要使用 computed() 函数提供一个计算属性

<template>
    <div>
        <h1>图书馆</h1>
        <button @click="changeBookName">修改书籍名称</button>
        <Book/>
    </div>
</template>
<script>
import { computed } from 'vue'
import Book from './Book.vue'
export default {
    components: {
        Book
    },
    provide() {
        return {
            bookName: computed(()=>this.bookName)
        }
    },
    data() {
        return {
            bookName: '三国演义'
        }
    },
    methods: {
        changeBookName() {
            this.bookName = '西游记'
        }
    }
    
}
</script>

图书组件Book(父)

<template>
    <div>
        <h2>书名</h2>
        <Title />
    </div>
</template>
<script>
import Title from './Title.vue'
export default {
   components: {
    Title
   }
}
</script>

标题组件Title(孙)

<template>
    <div>
        <p>标题</p>
        <p>{{bookName}}</p>
    </div>
</template>
<script>
export default {
    inject: ['bookName'],
}
</script>

运行效果

点击按钮,修改图书名称

3、注入别名

上面例子中标题组件Title(孙)中注入的 bookName,使用是也是bookName,即访问的本地属性名和注入名是相同的;如果我们想要用一个不同的本地属性名注入该属性,我们需要在 inject 选项的属性上使用对象的形式

看下面代码

注入bookName,本地属性使用 name

<template>
    <div>
        <p>标题</p>
        <p>{{name}}</p>
    </div>
</template>
<script>
export default {
    inject: {
        name: {
            from: 'bookName'
        }
    }
}
</script>

4、注入默认值

如果注入的属性没有任何组件提供,则会抛出一个运行时警告,如果注入一个值时不要求必须有提供者,那么我们应该声明一个默认值,和 props 类似

将图书馆组件Library(爷)中的provide注释掉

<template>
    <div>
        <h1>图书馆</h1>
        <button @click="changeBookName">修改书籍名称</button>
        <Book/>
    </div>
</template>
<script>
import { computed } from 'vue'
import Book from './Book.vue'
export default {
    components: {
        Book
    },
    // provide() {
    //     return {
    //         bookName: computed(()=>this.bookName)
    //     }
    // },
    data() {
        return {
            bookName: '三国演义'
        }
    },
    methods: {
        changeBookName() {
            this.bookName = '西游记'
        }
    }
    
}
</script>

图书组件Book(父)不变

<template>
    <div>
        <h2>书名</h2>
        <Title />
    </div>
</template>
<script>
import Title from './Title.vue'
export default {
   components: {
    Title
   }
}
</script>

标题组件Title(孙)中添加注入的默认值

<template>
    <div>
        <p>标题</p>
        <p>{{name}}</p>
    </div>
</template>
<script>
export default {
    inject: {
        name: {
            from: 'bookName',
            default: '红楼梦'
        }
    }
}
</script>

运行效果

 

5、应用层 Provide

除了在一个组件中提供依赖,我们还可以在整个应用层面提供依赖

在 main.js 中提供依赖

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.provide('title', '古典名著')
app.config.unwrapInjectedRef = true
app.mount('#app')

在标题组件Title(孙)中注入title

<template>
    <div>
        <p>标题</p>
        <p>{{ title }}</p>
        <p>{{name}}</p>
    </div>
</template>
<script>
export default {
    inject: {
        name: {
            from: 'bookName',
            default: '红楼梦'
        },
        title: {}
    }
}
</script>

运行效果

6、使用 Symbol 作注入名

如果有非常多的依赖提供,建议最好使用 Symbol 来作为注入名以避免潜在的冲突

笔者在components目录下定义keys.js文件

keys.js 文件内容

export const bookName = Symbol()

在图书馆组件Library(爷)中引入keys.js

<template>
    <div>
        <h1>图书馆</h1>
        <button @click="changeBookName">修改书籍名称</button>
        <Book/>
    </div>
</template>
<script>
import { computed } from 'vue'
import Book from './Book.vue'
import { bookName } from './keys.js'
export default {
    components: {
        Book
    },
    provide() {
        return {
            [bookName]: computed(()=>this.bookName)
        }
    },
    data() {
        return {
            bookName: '三国演义'
        }
    },
    methods: {
        changeBookName() {
            this.bookName = '西游记'
        }
    }
    
}
</script>

在标题组件Title(孙)中引入keys.js

<template>
    <div>
        <p>标题</p>
        <p>{{ title }}</p>
        <p>{{name}}</p>
    </div>
</template>
<script>
import { bookName } from './keys.js'
export default {
    inject: {
        name: {
            from: bookName,
            default: '红楼梦'
        },
        title: {}
    }
}
</script>

运行效果

 

至此完

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/376980.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

h5: 打开手机上的某个app

1、android端&#xff1a;直接通过URL Scheme方式打开。2、ios端&#xff08;2种&#xff09;&#xff1a;&#xff08;1&#xff09;使用URL Scheme方式打开。&#xff08;2&#xff09;使用Universal link方式打开。3、Universal link方式使用注意事项&#xff1a;&#xff0…

IM即时通讯开发群聊消息的已读回执功能该怎么实现?

我们平时在使用即时通讯应用时候&#xff0c;每当发出一条聊天消息&#xff0c;都希望对方尽快看到&#xff0c;并尽快回复&#xff0c;但对方到底有没有真的看到&#xff1f;我却并不知道。一个残酷的现实是&#xff0c;很多时候对方其实是早就已经看到了这条消息&#xff0c;…

Java “框架 = 注解 + 反射 + 设计模式” 之 注解详解

Java ”框架 注解 反射 设计模式“ 之 注解详解 每博一文案 刹那间我真想令时光停住&#xff0c;好让我回顾自己&#xff0c;回顾失去的年华&#xff0c;缅怀哪个穿一身短小的连衣裙 和瘦窄的短衫的小女孩。让我追悔少年时代&#xff0c;我心灵的愚钝无知&#xff0c;它轻易…

【Eye】Fake News Reading on Social Media: An Eye-tracking Study

Fake News Reading on Social Media: An Eye-tracking Study Abstract 在网上传播假新闻&#xff08;以及一般的虚假信息&#xff09;最近被认为是威胁整个社会的一个主要问题。这种传播在很大程度上是由于新的媒体形式&#xff0c;即社交网络和在线媒体网站。研究人员和从业…

Python WebDriver自动化测试

Webdriver Selenium 是 ThroughtWorks 一个强大的基于浏览器的开源自动化测试工具&#xff0c;它通常用来编写 Web 应用的自动化测试。 Selenium 2&#xff0c;又名 WebDriver&#xff0c;它的主要新功能是集成了 Selenium 1.0 以及 WebDriver​&#xff08;WebDriver 曾经是…

CentOS8基础篇7:Linux系统启动配置

一、Linux系统的启动过程 Linux的启动过程大体分为五个阶段&#xff1a; 1&#xff0e;计算机主机加电后&#xff0c;CPU初始化自身&#xff0c;接着在硬件固定位置执行一条指令。这条指令跳转到BIOS&#xff0c;BIOS找到启动设备并获取MBR&#xff0c;该MBR指向LILO或GRUB。 …

steam/csgo游戏搬砖,适合个人/团队操作的创业项目(内附详细操作流程)

不懂得小伙伴继续听我娓娓道来&#xff01; 首先准备工作&#xff0c;需要用到的软件&#xff1a; 软件&#xff1a; 1、电脑&#xff08;开网页不卡的就行&#xff09; 2、ti子 3、谷歌浏览器&#xff08;多开方便些&#xff0c;别的也可以&#xff09; 4、桌面令牌 5、…

Vue的表单处理全解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录表单处理知识点基本用法文本多行文本单选按钮复选框多个复选框选择框值绑定单选按钮复选框选择框修饰符.number.trim综合小练习表单处理 在日常的开发中&#xff0c…

urllib之urlopen和urlretrieve的headers传入以及parse、urlparse、urlsplit的使用

urllib库是什么?urllib库python的一个最基本的网络请求库&#xff0c;不需要安装任何依赖库就可以导入使用。它可以模拟浏览器想目标服务器发起请求&#xff0c;并可以保存服务器返回的数据。urllib库的使用&#xff1a;1、request.urlopen(1)只能传入url的方式from http.clie…

有状态登录和无状态登录详解

有状态登录和无状态登录详解一 有状态登录二 无状态登陆无状态登陆介绍&#xff1a;无状态token生成方式一 Jwt方式二 RSA256非对称加密方式三 区别与差异四 参考连接一 有状态登录 有状态登录(Session)&#xff1a; 传统上&#xff0c;我们会使用 Session 和 Cookie 来保存用…

云计算介绍

云计算介绍概述云分类服务模式应用起源传统 IT 技术存在的问题云计算的产生云计算的发展趋势主要特点关键技术关键技术一览表虚拟化桌面显示协议用户个性化配置海量数据并行计算云安全相关技术相关技术一览表分布式计算网格计算效用计算概述 云计算&#xff08;Cloud Computin…

rest和rpc的区别

一、rest&#xff1a; REST 不是一种协议&#xff0c;它是一种架构。大部分REST的实现中使用了RPC的机制&#xff0c;大致由三部分组成&#xff1a; 1、method&#xff1a;动词&#xff08;get、post之类的&#xff09; 2、Host&#xff1a;URI&#xff08;统一资源标识&…

华为OD机试题,用 Java 解【静态扫描最优成本】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

2023-02-28 mmap的原理及使用-思考

摘要: 最近在使用mmap解决数据库内存占用损耗过高导致OOM的问题, 不得不说在有些场景下mmap是非常有用. 本文主要涉及一些对mmap的思考. mmap本身的思考: mmap和文件系统的交互规则是什么mmap中给进程虚拟内存映射的文件上的部分,是什么? 为什么是页缓存? 有没有文件缓存?…

Vscode快速配置(1)之基础工具

VScode快速配置(1)之基础工具(v1.0) Author&#xff1a;Once Day Date&#xff1a;2023年2月19日 漫漫长路&#xff0c;才刚刚开始… &#xff08;嵌入式程序员开发环境&#xff09; 1. 概述 下面是一些基础插件&#xff0c;基本上嵌入式程序员都会用到。 首先是远程连接…

力扣-销售分析III

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1084. 销售分析III二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他总结…

Apache Hive入门

文章目录一、Apache Hive概述1.1、什么是Hive1.2、使用Hive原因1.3、Hive和Hadoop关系二、Hive功能思想2.1、映射信息记录2.2、SQL语法解析、编译三、Hive架构、组件3.1、Hive架构图3.2Hive组件四、Hive常用操作4.1、数据类型4.1.1、基本数据类型4.1.2、集合数据类型4.2、数据库…

动态网页的核心——JSP

文章目录1&#xff0c;JSP 概述2&#xff0c;JSP 小案例2.1 搭建环境2.2 导入 JSP 依赖2.3 创建 jsp 页面2.4 编写代码2.5 测试3&#xff0c;JSP 原理4&#xff0c;JSP 总结4.1 JSP的 缺点4.2技术的发展历程4.3JSP的必要性最后说一句1&#xff0c;JSP 概述 JSP&#xff08;全称…

IB数学/生物/化学/物理所需的教材有哪些

高中阶段的学习是迈向大学的重要步骤&#xff0c;涉及到的课程分为许多结构&#xff0c;其中最为常见的则是通过IB, AP和A-Level的学习&#xff0c;实现迈入国外大学的目的。 IB课程即国际文凭组织IBO&#xff08;International Baccalaureate Organization&#xff09;&#x…

「TCG 规范解读」规范结构

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…