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


Posted in Javascript onJune 15, 2017

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

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)

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

Javascript 相关文章推荐
Prototype源码浅析 Enumerable部分(二)
Jan 18 Javascript
js计算精度问题小结
Apr 22 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
Jan 28 Javascript
javascript框架设计之种子模块
Jun 23 Javascript
超赞的动手创建JavaScript框架的详细教程
Jun 30 Javascript
jQuery同步提交示例代码
Dec 12 Javascript
基于JavaScript代码实现兼容各浏览器的设为首页和加入收藏
Jan 07 Javascript
js实现三级联动效果(简单易懂)
Mar 27 Javascript
JavaScript实现时间表动态效果
Jul 15 Javascript
详解plotly.js 绘图库入门使用教程
Feb 23 Javascript
vue this.reload 方法 配置
Sep 12 Javascript
浅谈es6中的元编程
Dec 01 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 #Javascript
javascript完美实现给定日期返回上月日期的方法
Jun 15 #Javascript
JS自动生成动态HTML验证码页面
Jun 14 #Javascript
自定义vue全局组件use使用、vuex的使用详解
Jun 14 #Javascript
详解AngularJS 模块化
Jun 14 #Javascript
JS判断时间段的实现代码
Jun 14 #Javascript
bootstrap选项卡扩展功能详解
Jun 14 #Javascript
You might like
php求两个目录的相对路径示例(php获取相对路径)
2014/03/27 PHP
PHP扩展模块memcached长连接使用方法分析
2014/12/24 PHP
php微信开发之批量生成带参数的二维码
2016/06/26 PHP
php实现基于PDO的预处理示例
2017/03/28 PHP
javaScript Array(数组)相关方法简述
2009/07/25 Javascript
关于textarea提交的内容无法换行的解决办法
2013/04/09 Javascript
ExtJS4中的requires使用方法示例介绍
2013/12/03 Javascript
js跳转页面方法总结
2014/01/29 Javascript
js通过更改按钮的显示样式实现按钮的滑动效果
2014/04/23 Javascript
推荐 21 款优秀的高性能 Node.js 开发框架
2014/08/18 Javascript
node.js中的fs.mkdirSync方法使用说明
2014/12/17 Javascript
Nodejs的express使用教程
2015/11/23 NodeJs
Angularjs结合Bootstrap制作的一个TODO List
2016/08/18 Javascript
JS实现获取来自百度,Google,soso,sogou关键词的方法
2016/12/21 Javascript
如何为vuex实现带参数的 getter和state.commit
2019/01/04 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
2019/11/20 Javascript
[58:46]OG vs NAVI 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python 多线程抓取图片效率对比
2016/02/27 Python
matplotlib简介,安装和简单实例代码
2017/12/26 Python
Python模拟登录的多种方法(四种)
2018/06/01 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
2019/08/02 Python
python调用c++返回带成员指针的类指针实例
2019/12/12 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
python 安装库几种方法之cmd,anaconda,pycharm详解
2020/04/08 Python
150行python代码实现贪吃蛇游戏
2020/04/24 Python
python 实现性别识别
2020/11/21 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
Willer台湾:日本高速巴士/夜行巴士预约
2017/07/09 全球购物
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
大学新闻系求职信
2014/06/03 职场文书
商铺消防安全责任书
2014/07/29 职场文书
我的梦想演讲稿500字
2014/08/21 职场文书
销售业务员岗位职责
2015/02/13 职场文书
财务人员个人工作总结
2015/02/27 职场文书
Java日常练习题,每天进步一点点(38)
2021/07/26 Java/Android
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技