详解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 相关文章推荐
window.location.hash 使用说明
Nov 08 Javascript
javascript 实现字符串反转的三种方法
Nov 23 Javascript
js查看一个函数的执行时间实例代码
Sep 12 Javascript
JQuery中Ajax()的data参数类型实例分析
Dec 15 Javascript
Bootstrap 折叠(Collapse)插件用法实例详解
Jun 01 Javascript
node.js中EJS 模板快速入门教程
May 08 Javascript
jQuery实现动态给table赋值的方法示例
Jul 04 jQuery
javascript兼容性(实例讲解)
Aug 15 Javascript
vue父组件向子组件动态传值的两种方法
Nov 11 Javascript
Angularjs Promise实例详解
Mar 15 Javascript
更优雅的微信小程序骨架屏实现详解
Aug 07 Javascript
vue商城中商品“筛选器”功能的实现代码
Jul 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数据库调用类调用实例(详细注释)
2012/07/12 PHP
destoon整合UCenter图文教程
2014/06/21 PHP
如何利用http协议发布博客园博文评论
2015/08/03 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
yii2中的rules 自定义验证规则详解
2016/04/19 PHP
PHP 极验验证码实例讲解
2016/09/29 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
2018/01/29 PHP
php实现session共享的实例方法
2019/09/19 PHP
一个报数游戏js版(约瑟夫环问题)
2010/08/05 Javascript
javascript实现简单的二级联动
2015/03/19 Javascript
JavaScript类的写法
2016/09/17 Javascript
JavaScript实现时钟滴答声效果
2017/01/29 Javascript
vue里面使用mui的弹出日期选择插件实例
2018/09/16 Javascript
微信小程序之几种常见的弹框提示信息实现详解
2019/07/11 Javascript
微信公众号平台接口开发 菜单管理的实现
2019/08/14 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
详解vue高级特性
2020/06/09 Javascript
[05:40]DOTA2荣耀之路6:Wings最后进攻
2018/05/30 DOTA
Python探索之自定义实现线程池
2017/10/27 Python
python操作excel的方法
2018/08/16 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
pandas的qcut()方法详解
2019/07/06 Python
Django实现跨域请求过程详解
2019/07/25 Python
django2.2 和 PyMySQL版本兼容问题
2020/02/17 Python
Python如何读取、写入JSON数据
2020/07/28 Python
HTML5获取当前地理位置并在百度地图上展示的实例
2020/07/10 HTML / CSS
开业庆典邀请函
2014/01/08 职场文书
中式婚礼主持词
2014/03/13 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
2015年安全生产责任书
2015/01/30 职场文书
公司前台接待岗位职责
2015/04/03 职场文书
办公室管理规章制度
2015/08/04 职场文书
导游词之寿县报恩寺
2020/01/19 职场文书
web前端之css水平居中代码解析
2021/05/20 HTML / CSS
PyMongo 查询数据的实现
2021/06/28 Python