这里有新鲜出炉的 vue.js 教程,程序狗速度看过来!
Vue.js 是构建 web 界面的 JavaScript 库,提供数据驱动的组件,还有简单灵活的 API,使得 MVVM 更简单。
本篇文章主要介绍了详解 vue 跨组件通信的几种方法 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
在开发组件的时候,一定会遇到组件的通信,比如点击一个图标出现弹窗和蒙层,这三个分别是不同的组件。管理他们之间的状态就成了问题。
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)
来源: http://www.phperz.com/article/17/0813/338657.html