詳解vue跨組件通信的幾種方法
在開發(fā)組件的時候,一定會遇到組件的通信,比如點擊一個圖標出現(xiàn)彈窗和蒙層,這三個分別是不同的組件。管理他們之間的狀態(tài)就成了問題。
props雙向綁定
通過 sync 雙向綁定,屬性變化會同步到所有組件,這也是最簡單的實現(xiàn)方式,缺點是屬性會比較多。實現(xiàn)方式如下
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()">點擊出現(xiàn)彈窗</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() 派發(fā)事件傳遞給父組件,父組件 $broadcast() 廣播事件傳遞給子組件,這種方式雖然減少了props的使用,但是需要額外定義幾個事件,狀態(tài)多了就會變得很復(fù)雜,實現(xiàn)方法如下
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()">點擊出現(xiàn)彈窗</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
狀態(tài)統(tǒng)一放store管理,修改狀態(tài)通過mutations,組件通過action調(diào)用mutations,雖然有點繞,但是所有東西放一起后期會更好維護,實現(xiàn)方法如下
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()">點擊出現(xiàn)彈窗</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)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
前端vue如何通過URL訪問存儲在服務(wù)器或磁盤的圖片
在Vue中,通常需要將圖片存儲在服務(wù)器端,并通過url地址來訪問,下面這篇文章主要給大家介紹了前端vue如何通過URL訪問存儲在服務(wù)器或磁盤的圖片的相關(guān)資料,需要的朋友可以參考下2024-02-02詳解在vue-cli3.0中自定css、js和圖片的打包路徑
這篇文章主要介紹了詳解在vue-cli3.0中自定css、js和圖片的打包路徑,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Vue中使用Element UI的Table組件實現(xiàn)嵌套表格功能
這篇文章主要介紹了Vue中使用Element UI的Table組件實現(xiàn)嵌套表格功能,演示如何在Vue中使用Element UI的Table組件實現(xiàn)嵌套表格,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01vue3使用el-table實現(xiàn)新舊數(shù)據(jù)對比的代碼詳解
這篇文章主要為大家詳細介紹了在vue3中使用el-table實現(xiàn)新舊數(shù)據(jù)對比,文中的示例代碼講解詳細,具有一定的參考價值,需要的小伙伴可以參考一下2023-12-12