详解vue跨组件通信的几种方法

发布时间 - 2026-01-11 01:53:41    点击率:

在开发组件的时候,一定会遇到组件的通信,比如点击一个图标出现弹窗和蒙层,这三个分别是不同的组件。管理他们之间的状态就成了问题。

props双向绑定

通过 sync 双向绑定,属性变化会同步到所有组件,这也是最简单的实现方式,缺点是属性会比较多。实现方式如下

App.vue 文件

<template>
 <div id="app">
  <mask :hide-mask.sync="hideMask"></mask>
  <dialog :hide-dialog.sync="hideDialog" :hide-mask.sync="hideMask"></dialog>
  <dialog-icon :hide-dialog.sync="hideDialog" :hide-mask.sync="hideMask"></dialog-icon>
 </div>
</template>

<script>
import mask from './components/mask/index'
import dialog from './components/dialog/index'
import dialogIcon from './components/dialog-icon/index'

export default {
 components: {
  mask,
  dialog,
  dialogIcon
 },
 data () {
  return {
   hideMask: true,
   hideDialog: true
  }
 }
}
</script>

component/dialog/index.vue 文件

<template>
 <section class="dialog" :class="{ 'hide': hideDialog }">
  <div class="dialog-close" @click="hide()"></div>
 </section>
</template>

<script>
export default {
 props: ['hideDialog', 'hideMask'],
 methods: {
  hide () {
   this.hideDialog = !this.hideDialog
   this.hideMask = !this.hideMask
  }
 }
}
</script>

component/dialog-icon/index.vue 文件

<template>
 <section class="dialog-icon" @click="show()">点击出现弹窗</section>
</template>

<script>
export default {
 props: ['hideDialog', 'hideMask'],
 methods: {
  show () {
   this.hideDialog = !this.hideDialog
   this.hideMask = !this.hideMask
  }
 }
}
</script>

component/mask/index.vue 文件

<template>
 <div class="mask" :class="{ 'hide': hideMask }"></div>
</template>

<script>
export default {
 props: ['hideMask']
}
</script>

自定义事件

子组件 $dispatch() 派发事件传递给父组件,父组件 $broadcast() 广播事件传递给子组件,这种方式虽然减少了props的使用,但是需要额外定义几个事件,状态多了就会变得很复杂,实现方法如下

App.vue 文件

<template>
 <div id="app">
  <mask></mask>
  <dialog></dialog>
  <dialog-icon></dialog-icon>
</template>

<script>
import mask from './components/mask/index'
import dialog from './components/dialog/index'
import dialogIcon from './components/dialog-icon/index'

export default {
 components: {
  mask,
  dialog,
  dialogIcon
 },
 data () {
  return {
   hideMask: true,
   hideDialog: true
  }
 },
 events: {
  'dialog-dispatch' () {
   this.hidedialog = !this.hidedialog
   this.$broadcast('dialog-broadcast')
  },
  'mask-dispatch' () {
   this.hideMask = !this.hideMask
   this.$broadcast('mask-broadcast')
  }
 }
}
</script>

component/dialog-icon/index.vue 文件

<template>
 <section class="dialog-icon" @click="show()">点击出现弹窗</section>
</template>

<script>
export default {
 methods: {
  show () {
   this.$dispatch('dialog-dispatch')
   this.$dispatch('mask-dispatch')
  }
 },
 events: {
  'dialog-broadcast' () {
   this.hideDialog = !this.hideDialog
  }
 },
 data () {
  return {
   hideDialog: this.$parent.hideDialog,
   hideMask: this.$parent.hideMask
  }
 }
}
</script>

component/dialog/index.vue 文件

<template>
 <section class="dialog" :class="{ 'hide': hideDialog }">
  <div class="dialog-close" @click="hide()"></div>
 </section>
</template>

<script>
export default {
 methods: {
  hide () {
   this.$dispatch('dialog-dispatch')
   this.$dispatch('mask-dispatch')
  }
 },
 events: {
  'dialog-broadcast' () {
   this.hideDialog = !this.hideDialog
  }
 },
 data () {
  return {
   hideDialog: this.$parent.hideDialog,
   hideMask: this.$parent.hideMask
  }
 }
}
</script>

component/mask/index.vue 文件

<template>
 <div class="mask" :class="{ 'hide': hideMask }"></div>
</template>

<script>
export default {
 data () {
  return {
   hideMask: this.$parent.hideMask
  }
 },
 events: {
  'mask-broadcast' () {
   this.hideMask = !this.hideMask
  }
 }
}
</script>

Vuex

状态统一放store管理,修改状态通过mutations,组件通过action调用mutations,虽然有点绕,但是所有东西放一起后期会更好维护,实现方法如下

App.vue 文件

<template>
 <div id="app">
  <mask></mask>
  <dialog></dialog>
  <dialog-icon></dialog-icon>
 </div>
</template>

<script>
import mask from './components/mask/index'
import dialog from './components/dialog/index'
import dialogIcon from './components/dialog-icon/index'

export default {
 components: {
  mask,
  dialog,
  dialogIcon
 }
}
</script>

component/dialog/index.vue 文件

<template>
 <section class="storehouse dialog" :class="{ 'hide': isHideDialog }">
  <div class="dialog-close" @click="hideDialog()"></div>
 </section>
</template>

<script>
import { hideDialog } from '../../vuex/actions'

export default {
 vuex: {
  state: {
   isHideDialog: state => state.isHideDialog
  },
  actions: {
   hideDialog
  }
 }
}
</script>

component/dialog-icon/index.vue 文件

<template>
 <section class="storehouse-icon" @click="hideDialog()">点击出现弹窗</section>
</template>

<script>
import { hideDialog } from '../../vuex/actions'

export default {
 vuex: {
  actions: {
   hideDialog
  }
 }
}
</script>

component/mask/index.vue 文件

<template>
 <div class="mask" :class="{ 'hide': isHideMask }"></div>
</template>

<script>
export default {
 vuex: {
  state: {
   isHideMask: state => state.isHideMask
  }
 }
}
</script>

vuex/store.js 文件

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'

Vue.use(Vuex)

const state = {
 isHideMask: true,
 isHideDialog: true
}

const store = new Vuex.Store({
 state,
 mutations
})

if (module.hot) {
 module.hot.accept(['./mutations'], () => {
  const mutations = require('./mutations').default
  store.hotUpdate({
   mutations
  })
 })
}

export default store

vuex/mutations.js 文件

import {
 HIDEDIALOG
}
from './mutation-types'

export
default {
 [HIDEDIALOG] (state) {
  state.isHideDialog = !state.isHideDialog
  state.isHideMask = !state.isHideMask
 }
}

vuex/mutations-types.js 文件

export const HIDEDIALOG = 'HIDEDIALOG'

vuex/action.js 文件

import { HIDEDIALOG } from './mutation-types'
export const hideDialog = ({ dispatch }) => dispatch(HIDEDIALOG)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# vue  # 跨组件通信  # vuex  # 跨组件调用方法  # Vue.js每天必学之组件与组件间的通信  # Vuejs第十篇之vuejs父子组件通信  # vue中组件通信的八种方式(值得收藏!)  # vue 组件间的通信之子组件向父组件传值的方式  # Vue 之孙组件向爷组件通信的实现  # 深入探讨Vue.js组件和组件通信  # 详解vue组件通信的三种方式  # Vue3的7种种组件通信详情  # 详细聊聊vue组件是如何实现组件通讯的  # 绑定  # 方法如下  # 几个  # 就会  # 较多  # 自定义  # 会比  # 最简单  # 这三个  # 他们之间  # 大家多多  # 很复杂  # 后期  # 这也是  # 减少了  # 就成了  # div  # id  # app  # lt 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭  创业网站制作流程,创业网站可靠吗?  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  如何快速上传建站程序避免常见错误?  Laravel如何实现多对多模型关联?(Eloquent教程)  Bootstrap整体框架之CSS12栅格系统  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  BootStrap整体框架之基础布局组件  Laravel如何使用模型观察者?(Observer代码示例)  网站建设保证美观性,需要考虑的几点问题!  简历在线制作网站免费版,如何创建个人简历?  java获取注册ip实例  EditPlus中的正则表达式实战(5)  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  HTML 中动态设置元素 name 属性的正确语法详解  PHP正则匹配日期和时间(时间戳转换)的实例代码  如何快速搭建自助建站会员专属系统?  Laravel观察者模式如何使用_Laravel Model Observer配置  如何登录建站主机?访问步骤全解析  高性价比服务器租赁——企业级配置与24小时运维服务  Laravel怎么使用Intervention Image库处理图片上传和缩放  在线制作视频网站免费,都有哪些好的动漫网站?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  如何在宝塔面板中创建新站点?  车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  如何确保西部建站助手FTP传输的安全性?  Laravel集合Collection怎么用_Laravel集合常用函数详解  Laravel控制器是什么_Laravel MVC架构中Controller的作用与实践  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  Laravel Docker环境搭建教程_Laravel Sail使用指南  Laravel API资源类怎么用_Laravel API Resource数据转换  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  佛山网站制作系统,佛山企业变更地址网上办理步骤?  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  浅谈Javascript中的Label语句  如何在香港服务器上快速搭建免备案网站?  Python高阶函数应用_函数作为参数说明【指导】  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  浅述节点的创建及常见功能的实现  动图在线制作网站有哪些,滑动动图图集怎么做?  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  Laravel如何实现用户密码重置功能?(完整流程代码)  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  Angular 表单中正确绑定输入值以确保提交与验证正常工作  如何彻底卸载建站之星软件?