vue 组件通信方式

  1. 父组件将自己的状态分享给子组件使用;

    方法:父组件通过子标签传递数据,子组件通过 props 接收

  2. 子组件改变父组件的状态;

    方法:父组件在子标签上通过@abc 提供一个改变自身状态的方法,子组件通过$emit("abc", payload)触发这个函数

  3. 父组件直接改变子组件的状态;

    方法:父组件设法($ref,$children[0])拿到子组件实例对象,然后通过实例对象直接修改子组件状态

  4. 子组件直接改变父组件的状态

    方法:子组件通过$parent拿到父组件的改变自身状态的方法,然后直接调用($parent 可以拿到父组件状态,但是最好不要直接修改,而是通过父组件函数式修改,保持单向数据流)

  5. 父组件通过插槽向子组件传递数据

    方法:子组件定义具名插槽,父组件向插槽内传递自己的状态

  6. 父组件向后代组件传值

    方法:父组件正常在标签上向子组件传递数据,子组件不用 props 接收属性,通过$attrs获取属性,通过$listeners 获取方法。子组件再向下传递时,使用 v-bind="$attr"传递属性,使用v-on="$listeners"传递方法

  7. 父组件向后代组件传值

    方法:父组件js中定义provide函数提供数据源,后代组件通过inject去接收,inject可以是一个数组或对象。

    注意:父组件提供的数据源如果不是响应式的,那么后代修改数据,数据不会响应变化。如果父组件提供的数据源是响应式的,但是不是一个对象,那么它也不是响应式的,所以要用对象在外包一层对象(数组不行)。另外,如果子组件同时provide一个inject祖先组件相同名称的数据,那么子组件的后代会就近使用子组件的数据。

    官网tip:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

    https://cn.vuejs.org/v2/api/#provide-inject

  8. 全局通信-事件总线

    方法:通过注册一个新的vue实例作为桥梁,使用$on和$emit来完成通信

  9. 全局通信-vuex

    略(看官方文档喽)

    https://vuex.vuejs.org/zh/

第一种: props传参

// 父组件向子组件传递msg
<template>
<div>
<p>我是dad</p>
<Child :msg="msg" />
</div>
</template> <script>
import Child from "./ChildItem.vue"; export default {
name: "App",
components: {
Child,
},
data() {
return {
msg: "父亲的忠告",
};
},
};
</script> // 子组件props接收
<template>
<div>
<p>我是子组件</p>
<span>{{ msg }}</span>
</div>
</template> <script>
export default {
props: {
msg: {
type: String,
default: "什么都没有",
},
},
};
</script>

第二种:emit,on通信

// 父组件向子组件提供改变自己状态的函数
<template>
<div>
<p>我是dad</p>
<Child @changeMyMind="changeMyMind" />
<span>{{ mind }}</span>
</div>
</template> <script>
import Child from "./ChildItem.vue"; export default {
name: "App",
components: {
Child,
},
data() {
return {
mind: "伟大万岁",
};
},
methods: {
changeMyMind(yourMind) {
this.mind = yourMind;
},
},
};
</script> // 子组件不用接收,直接通过$emit触发并传参就行
<template>
<div>
<p>我是子组件</p>
</div>
</template> <script>
export default {
mounted() {
this.$emit("changeMyMind", "躺平鸟");
},
};
</script>

第三种:$ref,$children实例通信

// 父组件通过$ref或者$children拿到子组件实例,然后直接修改子组件状态
/**
* this.$children`数组中的元素不是响应式的,并且下标并不一定对用父组件引用的子组件的顺序,例如有异步加载的子组件,可能影响其在 children 数组中的顺序。所以使用时需要根据一定的条件例如子组件的name去找到相应的子组件。
**/
<template>
<div>
<p>我是dad</p>
<Child ref="childRef" />
</div>
</template> <script>
import Child from "./ChildItem.vue"; export default {
components: {
Child,
},
mounted() {
// this.$children[0].childMsg = "不你不是";
this.$refs.childRef.childMsg = "不你不是";
},
};
</script> // 子组件等着被改就行
<template>
<div>
<p>我是子组件</p>
<span>{{ childMsg }}</span>
</div>
</template> <script>
export default {
data() {
return {
childMsg: "我是子组件数据",
};
},
};
</script>

第四种:$parent通信

// 父组件
<template>
<div>
<p>我是dad</p>
<Child />
<span>{{ aa }}</span>
</div>
</template> <script>
import Child from "./ChildItem.vue"; export default {
components: {
Child,
},
data() {
return {
aa: "",
};
},
methods: {
changeAa(data) {
this.aa = data;
},
},
};
</script> // 子组件通过$parent拿到父组件实例,然后直接修改父组件状态
<template>
<div>
<p>我是子组件</p>
<span>{{ childMsg }}</span>
</div>
</template> <script>
export default {
data() {
return {
childMsg: "我是子组件数据",
};
},
mounted() {
// this.$parent.aa = "我改了哈"; 不推荐
this.$parent.changeAa("我改了哦");
},
};
</script>

第五种:插槽通信(一般不用)

// 父组件
<template>
<div>
<p>我是dad</p>
<Child>
<template v-slot:boring>
{{ aa }}
</template>
</Child>
</div>
</template> <script>
import Child from "./ChildItem.vue"; export default {
components: {
Child,
},
data() {
return {
aa: "父组件的数据哦",
};
},
};
</script> // 子组件定义插槽
<template>
<div>
<p>我是子组件</p>
<slot name="boring"></slot>
</div>
</template> <script>
export default {};
</script>

第六种:$attr,$listener深层双向通信

// 父组件
<template>
<div>
<p>我是dad</p>
<span>{{ dadData }}</span>
<Son :dadData="dadData" @changeDadData="changeDadData" @keyup="someKeyUp" />
</div>
</template> <script>
import Son from "./SonItem.vue"; export default {
components: {
Son,
},
data() {
return {
dadData: "父组件的数据哦",
};
},
methods: {
changeDadData(newData) {
this.dadData = newData;
},
someKeyUp(e) {
console.log(e.target.value);
},
},
};
</script> // 儿子组件
<template>
<div>
<p>我是儿子组件</p>
<span>{{ $attrs.dadData }}</span>
<input type="text" v-on="$listeners" />
<GrandSon v-bind="$attrs" v-on="$listeners" />
</div>
</template> <script>
import GrandSon from "./GrandSon.vue"; export default {
components: {
GrandSon,
},
mounted() {
console.log(this.$listeners);
},
};
</script> // 孙子组件
<template>
<div>
<p>我是孙子组件</p>
<input type="text" @input="grandsonInput" />
</div>
</template> <script>
export default {
methods: {
grandsonInput(e) {
// this.$emit("changeDadData", e.target.value); 也可以触发
this.$listeners.changeDadData(e.target.value);
},
},
};
</script>

第七种:provide,inject依赖注入深层次单向通信

// 父组件
<template>
<div>
<p>我是dad</p>
<span>{{ dadMessage }}</span>
<Son />
</div>
</template> <script>
import Son from "./SonItem.vue"; export default {
components: {
Son,
},
provide() {
return {
message: this.dadMessage,
};
},
data() {
return {
dadMessage: {
textContent: "我是个祖先数据",
},
};
},
};
</script> // 儿子组件
<template>
<div>
<p>我是儿子组件</p>
<span>{{ theData }}</span>
<GrandSon />
</div>
</template> <script>
import GrandSon from "./GrandSon.vue"; export default {
components: {
GrandSon,
},
inject: {
// 起个别名
theData: {
// 数据来源映射
from: "message",
// 默认值
default: () => ({ message: { textContent: "啥也不是" } }),
},
},
};
</script> // 孙子组件
<template>
<div>
<p>我是孙子组件</p>
<input type="text" @input="grandsonInput" />
<span>{{ message.textContent }}</span>
</div>
</template> <script>
export default {
methods: {
grandsonInput(e) {
this.message.textContent = e.target.value;
},
},
inject: ["message"],
};
</script>

第八种: $bus事件总线全局通信

// 父组件通过this.$bus.$on监听事件
<template>
<div>
<p>我是dad</p>
<span>{{ dadData }}</span>
<Son />
</div>
</template> <script>
import Son from "./SonItem.vue"; export default {
components: {
Son,
},
data() {
return {
dadData: "我是爹地",
};
},
mounted() {
this.$bus.$on("changeDadData", this.changeDadData);
},
methods: {
changeDadData(newData) {
this.dadData = newData;
},
},
// 记得清除监听
beforeDestroy() {
this.$bus.$off("changeDadData");
},
};
</script> // 孙子组件通过this.$bus.$emit触发事件
<template>
<div>
<p>我是孙子组件</p>
<input type="text" @input="grandsonInput" />
<span></span>
</div>
</template> <script>
export default {
methods: {
grandsonInput(e) {
this.$bus.$emit("changeDadData", e.target.value);
},
},
};
</script>

一文搞定Vue2组件通信的更多相关文章

  1. 一文搞定 SonarQube 接入 C#(.NET) 代码质量分析

    1. 前言 C#语言接入Sonar代码静态扫描相较于Java.Python来说,相对麻烦一些.Sonar检测C#代码时需要预先编译,而且C#代码必须用MSbuid进行编译,如果需要使用SonarQub ...

  2. 一文搞定MySQL的事务和隔离级别

    一.事务简介 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成. 一个数据库事务通常包含了一个序列的对数据库的读/写操作.它的存在包含有以下两个目的: 为数据库操作序列提供 ...

  3. 一文搞定scrapy爬取众多知名技术博客文章保存到本地数据库,包含:cnblog、csdn、51cto、itpub、jobbole、oschina等

    本文旨在通过爬取一系列博客网站技术文章的实践,介绍一下scrapy这个python语言中强大的整站爬虫框架的使用.各位童鞋可不要用来干坏事哦,这些技术博客平台也是为了让我们大家更方便的交流.学习.提高 ...

  4. 一文搞定Spring Boot + Vue 项目在Linux Mysql环境的部署(强烈建议收藏)

    本文介绍Spring Boot.Vue .Vue Element编写的项目,在Linux下的部署,系统采用Mysql数据库.按照本文进行项目部署,不迷路. 1. 前言 典型的软件开发,经过" ...

  5. 来吧!一文彻底搞定Vue组件!

    作者 | Jeskson 来源 | 达达前端小酒馆 Vue组件的概述 组件是什么呢,了解组件对象的分析,Vue组件中的data属性,props传递数据的原理到底是什么. 事件通信的那些事 如何了解父子 ...

  6. 21.SpringCloud实战项目-后台题目类型功能(网关、跨域、路由问题一文搞定)

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  7. 一文搞定FastDFS分布式文件系统配置与部署

    Ubuntu下FastDFS分布式文件系统配置与部署 白宁超 2017年4月15日09:11:52 摘要: FastDFS是一个开源的轻量级分布式文件系统,功能包括:文件存储.文件同步.文件访问(文件 ...

  8. 一文搞定 Redis 复制(全会的举个手看看)

    阅读本文大概需要 5 分钟. 本文大纲 复制过程 数据间的同步 全量复制 部分复制 心跳 异步复制 总结 一.复制过程 Step 1:从节点执行 slaveof 命令. Step 2:从节点只是保存了 ...

  9. 一文搞定全场景K3s离线安装

    作者简介 王海龙,Rancher中国社区技术经理,负责Rancher中国技术社区的维护和运营.拥有6年的云计算领域经验,经历了OpenStack到Kubernetes的技术变革,无论底层操作系统Lin ...

随机推荐

  1. RocketMq 完整部署

    目录 RocketMq 部署 环境 物理机部署 自定义日志目录 自定义参数和数据存放位置 服务启动 启动name server 启动broker 关停服务 尝试发送消息 常见报错 部署 rockerm ...

  2. 被迫开始学习Typescript —— interface

    一开始以为,需要使用 class 来定义呢,学习之后才发现,一般都是使用 interface 来定义的. 这个嘛,倒是挺适合 js 环境的. 参考:https://typescript.bootcss ...

  3. 单源最短路问题:OJ5——低德地图

    本题就是一道单源最短路问题.由于是稀疏图,我们采用Dijkstra算法. Dijkstra算法原理 Dijkstra算法的步骤 我们把所有的节点分为两个集合:被选中的(visited==1) 和 未被 ...

  4. 详解CVE-2022-0847 DirtyPipe漏洞

    摘要:本文详细介绍了CVE-2022-0847漏洞形成根因,相应补丁修复方法,通过本文让读者对CVE-2022-0847漏洞有更清晰的了解. 本文分享自华为云社区<CVE-2022-0847 D ...

  5. Linux篇-The slave I/O thread stops because master and slave have equal...

    1)操作系统 cat /etc/issue CentOS release 6.6 (Final) Kernel \r on an \m cat /proc/version Linux version ...

  6. Flask_WTF实现表单

    Flask_WTF实现表单可分为六个步骤: ①导入FlaskForm扩展包(from flask_wtf import FlaskForm) ②导入StringField,PasswordField, ...

  7. 判断数据类型(typeof&instanceof&toString)

    一.数据类型 ES6规范中有7种数据类型,分别是基本类型和引用类型两大类 基本类型(简单类型.原始类型):String.Number.Boolean.Null.Undefined.Symbol 引用类 ...

  8. MySQL数据库和Oracle数据库的区别

    Mysql数据库 由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司.是一种中小型的关系型数据库. MySQL 数据库体积小.速度快.总体拥有成本低.开放源代码,其有着广泛的应用,一般中 ...

  9. 19.Tomcat多实例部署及负载均衡、动静分离

    Tomcat多实例部署及负载均衡.动静分离 目录 Tomcat多实例部署及负载均衡.动静分离 Tomcat多实例部署 安装jdk 设置jdk环境变量 安装tomcat 配置 tomcat 环境变量 修 ...

  10. 第三章、DNS域名解析服务

    DNS 1DNS简介 域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务.它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.DNS ...