vue跨組件通信的幾種方法


http://www.tuicool.com/articles/jyM32mA

在開發組件的時候,一定會遇到組件的通信,比如點擊一個圖標出現彈窗和蒙層,這三個分別是不同的組件。管理他們之間的狀態就成了問題。

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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM