【Vue组件通信方式】

news2024/11/24 1:08:15

文章目录

  • 前言
  • 一、父子组件通信
    • 1、父传子
      • ①使用`props`接收父组件传递的属性
      • ② 使用`$attrs`接收父组件未在 `props` 和 `emits` 中定义的属性和事件
      • ③使用 `$parent`获取父组件的信息
    • 2、子传父
      • ① 使用 `$emit`传递信息给父组件
      • ② 使用`$refs`获取子组件的属性和事件
  • 二、自定义事件:适用于兄弟组件或“距离”较远的组件
  • 三、多级组件上下级:`provide`、`inject`
  • 总结


前言

组件通信在工作中很常见,但通讯的方式很多且使用场景也不同,故在此记录和总结。

一、父子组件通信

1、父传子

①使用props接收父组件传递的属性

// 父组件
<template>
 <Helloword :msg=msg />
</template>

<script>
export default {
  data() {
    return {
      msg: 'message'
    }
  }
}
</script>
// 子组件
<template>
  <h1>{{ msg }}</h1>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
}
</script>

② 使用$attrs接收父组件未在 propsemits 中定义的属性和事件

  • 父组件level1,向level2传递属性a、b、c和事件getA()、getB()、getC()
// level1.vue
<template>
    <p>Level1</p>
    <Level2
        :a="a"
        :b="b"
        :c="c"
        @getA="getA" 
        @getB="getB"
        @getC="getC"
    ></Level2>
</template>

<script>
import Level2 from './Level2'

export default {
    name: 'Level1',
    components: { Level2 },
    data() {
        return {
            a: 'aaa',
            b: 'bbb',
            c: 'ccc'
        }
    },
    methods: {
        getA() {
            return this.a
        },
        getB() {
            return this.b
        },
        getC() {
            return this.c
        }
    }
}
</script>
  • 组件level2使用this.$attrs,接收父组件未在 propsemits 中定义的属性和事件
// level2.vue
<template>
    <p>Level2</p>
    <Level3
        :x="x"
        :y="y"
        :z="z"
        @getX="getX"
        @getY="getY"
        @getZ="getZ"
        v-bind="$attrs"
    ></Level3>
</template>

<script>
import Level3 from './Level3'

export default {
    name: 'Level2',
    components: { Level3 },
    props: ['a'],
    emits: ['getA'],
    data() {
        return {
            x: 'xxx',
            ...
        }
    },
    methods: {
        getX() {
            return this.x
        }
        ...
    },
    created() {
        console.log('level2', Object.keys(this.$attrs)) // 是 props 和 emits 后补
    },
}
</script>

在这里插入图片描述

  • 子组件level3接收父组件level2中,未被propsemits接收的属性和事件。level2组件中定义level3组件时,使用v-bind="$attrs"可接收level1中未在 propsemits 中定义的属性和事件。
<template>
    <p>Level3</p>
</template>

<script>
export default {
    name: 'Level3',
    props: ['x'],
    emits: ['getX'],
    inheritAttrs: false, // 避免在dom节点中,增加传递的属性,如:<p b='b' c='c'></p>。使用attrs,在只有一个根元素时,就会生成
    created() {
         console.log('level3', Object.keys(this.$attrs)) // 是 props 和 emits 候补
    }
}
</script>

在这里插入图片描述

$attrs可以实现多级组件传递,但是依赖v-bind="$attrs"。它是 props 和 emits 候补

③使用 $parent获取父组件的信息

   mounted() {
        console.log(this.$parent.getX())
    },

2、子传父

① 使用 $emit传递信息给父组件

父组件

<template>
  <HelloWorld :getMsg="getMsg"/>
</template>

<script>
export default {
  name: 'HelloWorld',
  methods: {
    getMsg(msg) {
    	console.log(msg);
    }
  },
}

子组件

// 子组件:HelloWorld
<template>
   <button @click = "clickHandler">传递</button>
</template>

<script>
export default {
  name: 'HelloWorld',
 // emits: ['showMsg'], // Vue3
  methods: {
    clickHandler() {
      this.$emit('getMsg', 'hello world')
    }
  },
}
</script>

② 使用$refs获取子组件的属性和事件

父组件

<template>
    <p>Level3</p>
    <HelloWorld msg="hello 双越" ref="hello1"/> // 子组件
</template>
<script>
import HelloWorld from '../HelloWorld'
export default {
    ...
    mounted() {
        console.log(this.$refs.hello1.name) // created里面组件未渲染完成,需要再mounted里面获取
    },
}
</script>

二、自定义事件:适用于兄弟组件或“距离”较远的组件

兄弟组件1

<template>
  <p><button @click="trigger">点击传值</button></p>
</template>

<script>
import event from '../utils/event.js'

export default {
  name: 'CustomEvent2',
  methods: {
    trigger() {
      event.emit('showMsg', 'hello custom event') // 触发事件
    }
  },
}
</script>

// 兄弟组件2

<template>
  <p>接收值</p>
</template>

<script>
import event from '../utils/event.js'

export default {
  name: 'CustomEvent1',
  methods: {
    showMsg(msg) {
      console.log(msg)
    }
  },
  mounted() {
    event.on('showMsg', this.showMsg) //绑定事件
  },
  // Vue2.x beforeDestroy
  beforeUnmount() {
    event.off('showMsg', this.showMsg) // 组件销毁需要off事件。否则会造成内存泄漏
  },
}
</script>

Vue 版本的区别

  • Vue 2.x 可以使用 Vue 实例作为自定义事件
  • Vue 3.x 需要使用第三方的自定义事件,例如 https://www.npmjs.com/package/event-emitter

自定义事件可能出现多个触发多个绑定,所以,容易造成项目混乱,用的时候要遵守规范。

三、多级组件上下级:provideinject

传递数据的组件,使用provide传递

<template>
    <p>Level1: <input v-model="name"></p>
    <Level2></Level2>
</template>

<script>
import { computed } from 'vue'
import Level2 from './Level2'
export default {
    name: 'Level1',
    components: { Level2 },
    data() {
        return {
            name: 'lisa'
        }
    },
    provide() {
        return {
            info: computed(() => this.name) // cmputed包裹响应式数据,实现下级组件数据响应式
        }
    }
}
</script>

需要被传递数据的组件使用inject接收。支持多层或多个组件接收。

<template>
    <p>Level2 {{info}}</p>
    <Level3></Level3>
</template>

<script>
import Level3 from './Level3'

export default {
    name: 'Level2',
    components: { Level3 },
    inject: ['info']
}
</script>

在这里插入图片描述

总结

  • 父子组件通讯
    • props emits this.$emit
    • $attrs (也可以通过 v-bind="$attrs" 向下级传递)
    • $parent $refs
  • 多级组件上下级
    • provide inject
  • 跨级、全局
    • 自定义事件
    • Vuex

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

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

相关文章

独家丨DeepMind科学家、AlphaTensor一作解读背后的故事与实现细节

一直以来&#xff0c;DeepMind的Alpha系列工作&#xff0c;AlphaGo、AlphaStar等致力于棋类和游戏应用中战胜人类&#xff0c;而两个月前发布的AlphaTensor则把目标指向了科学计算领域&#xff0c;意在为矩阵乘法等基本计算任务自动设计更高效的经典算法&#xff0c;这一工作一…

Burpsuite超详细安装教程(附安装包)

写在开头 Burp Suite 是用于攻击web 应用程序的集成平台&#xff0c;包含了许多工具。Burp Suite为这些工具设计了许多接口&#xff0c;以加快攻击应用程序的过程。所有工具都共享一个请求&#xff0c;并能处理对应的HTTP 消息、持久性、认证、代理、日志、警报。 接下来我来…

软件测试面试经 | 双非院校,从外包到外企涨薪85%,他的涨薪秘籍全公开

本文为霍格沃兹测试开发学社优秀学员跳槽笔记&#xff0c;测试开发进阶学习文末加群。 本身是一所不入流的院校毕业的一名建工类专业的瓜娃子&#xff0c;至今记得当初是因为找工作被培训公司忽悠才加入到这个行业的&#xff0c;抱着做着试试的想法这一干在深圳就是6年&#xf…

excel替换技巧:如何将手机号码的部分数字变成星号

每个销售员经常会接触大量客户&#xff0c;会用小本本记下众多客户的信息&#xff0c;而手机号码就是其中重要的一项。为了保护客户隐私&#xff0c;在公开的信息里销售员需要把客户手机号码的部分数字变成星号。比如说&#xff0c;把客户A的手机号码15867852976修改成158****2…

SpringMvc源码分析(三) 请求执行过程之获取MethodHandler

1.请求是如何关联到DispatcherServlet的 DispatcherServlet是Servlet的实现&#xff0c;遵循Servlet生命周期的规则。 Servlet的生命周期即其出生到死亡的过程中分别会调用Servlet里的以下方法&#xff1a; 加载和实例化&#xff1a;可以参考SpringMvc源码分析一 init方法…

【JavaEE】博客前端

目录 一、列表页 1.1导航条 1.2主题区域 1.2.1个人信息框 1.2.2 内容区 二、登录页 三、详情页 一、列表页 整体布局如下&#xff1a; 1.1导航条 导航条分为三块&#xff0c;整体都设置id为导航栏&#xff0c;然后左右分为导航栏左和导航栏右。左边靠左&#xff0c;右边靠…

计算机视觉Computer Vision课程学习笔记四之Region and Edge Descriptions

第四章讲了区域和边界的描述 包括最佳区域评估方法&#xff0c;多物体识别&#xff0c;标签算法&#xff0c;斑点标记 以及矩评估的方法和优劣 Region Description Simple measurements on binary images • Use for recognition, etc. • Generate region descriptions whic…

Win10+CMake+VS2017编译OpenCV4.5.5

第一步&#xff1a;准备工作1 下载opencv4.5.5下载OpenCV4.5.5&#xff0c;并解压到自己新建文件夹opencv下。2 下载opencv_contrib4.5.5下载opencv_contrib4.5.5&#xff0c;解压到上面的opencv文件夹中&#xff0c;并在opencv文件夹中新建一个build文件夹&#xff0c;用来存放…

第一天总结 之 用户管理界面的实现 之 添加操作 的实现

添加操作的实现 明确页面的跳转 找到 admin_adduser.jsp中 form表单 前端的添加页面展示 在表单中输入 信息 点击注册跳转到 from表单对应的 action地址 UserAddServlet 创建UserAddServlet 从前端的form表单中获取值 然后在service层 进行 业务操作 即将这些属性存放在 Ob…

私有部署与SaaS模式网站有什么区别

什么是SaaS SaaS 是 Software-as-a-Service 的简称&#xff0c;它是一种通过互联网提供软件的模式。 以官网为例&#xff0c;SaaS订阅的网站通常统一部署在SaaS提供商的云服务器上。用户通过自己的实际需求订购对应的网站系统服务&#xff0c;按订购的系统功能、使用流量/存储…

Word处理控件Aspose.Words功能演示:用Java从Word文档中提取文本

Aspose.Words For .NET是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c;API支持所有流行的Word…

凭记忆错题记录-

3、某种部件用在2000合计算机系统中&#xff0c;运行工作1000小时后&#xff0c;其中有4台计算机的这种部件失效&#xff0c;则该部件的千小时可靠性度R为()。 A.0.990 B.0.992 C.0.996 D.0.998 【参考答案】D  8、9、X509数字证书标准推荐使用的密码算法是(8)&#xff0c;而…

计算机视觉Computer Vision课程学习笔记八之Recognition识别 low level

第八章讲了全局图像识别的方法 距离 空间特征 简单的分类模型 Recognition (low level / global matching) Task – from a description of the image in terms of “good” features (not just blobs) extract a meaning • Detect • Classify • Etc. • Techniques – Te…

C++动态规划超详细总结

动态规划首先来介绍一下动态规划&#xff0c;但我不想用过于官方的语言来介绍。动态规划是一种思想&#xff0c;它常用于最优解问题&#xff08;即所有问题包括所有子问题的解为最优解&#xff09;&#xff0c;它有点像递推&#xff0c;是在已知问题的基础上解决其他问题。这种…

【openWrt】安装后进行定制

修改openWrt管理后台默认端口vim /etc/config/uhttpd修改如下图内容然后重启uhttpd服务即可生效etc/init.d/uhttpd restart修改openWrt软件包源可以在openwrt后台改也可以在/etc/opkg/distfeeds.conf直接改vim /etc/opkg/distfeeds.conf配置如下src/gz handsomemod_core https:…

通讯录的实现

问天下谁与争锋&#xff0c;唯我傲视苍穹 此句赠与在看文章的你 该通讯录使用的语言是C语言&#xff0c;涉及的知识有动态开辟内存&#xff0c;和文件内存管理。 动态开辟内存是用来不断给通讯录增加容量的 文件管理是用来将通讯录的信息存储到文件里。 我会先从简单的写起&am…

公司裁员70%,小组从20个人降到5个人,年底公司耍无赖,全员打绩效C,就为了不发年终奖!...

年终奖写进合同&#xff0c;公司还能耍赖不给吗&#xff1f;一位网友吐槽&#xff1a;坐标小公司&#xff0c;公司裁员70%&#xff0c;自己组从20个人降到5个人。现在年底了&#xff0c;公司耍无赖&#xff0c;全员打绩效C&#xff0c;就为了不发年终奖&#xff01;年终奖都是写…

454. 四数相加 II 383. 赎金信 15. 三数之和 18. 四数之和

454. 四数相加 II 巧用哈希表&#xff0c;哈希表键值对对应的是两数之和&#xff0c;两数之和出现次数。 首先定义 一个unordered_map&#xff0c;key放a和b两数之和&#xff0c;value 放a和b两数之和出现的次数。遍历大A和大B数组&#xff0c;统计两个数组元素之和&#xff0…

Nginx与LUA(4)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e;Nginx既然可以限制流量&#xff0c;那能不能「扩展」流量呢&#xff1f;当然可以&#xff0c;但可能不是你想象的那种「扩展」&#xff0c;更准确地来说是复制&am…

KVM虚拟化基本操作

1&#xff0c;虚拟化的一些介绍 虚拟化软件是可以让一台物理主机建立与执行一至多个虚拟化环境的软件&#xff0c;虚拟化将硬件、操作系统和应用程序一同封装一个可迁移的虚拟机档案文件中。 安装位置分类 目前从Hypervisor(虚拟机管理程序)安装位置分类&#xff0c;虚拟化层…