Vue2的组件通讯有哪些

发布时间:2022-10-21 17:00:01 作者:iii
来源:亿速云 阅读:158

Vue2的组件通讯有哪些

目录

  1. 引言
  2. 父子组件通讯
  3. 子父组件通讯
  4. 兄弟组件通讯
  5. 跨级组件通讯
  6. 全局事件总线
  7. Vuex状态管理
  8. 总结

引言

在Vue.js中,组件是构建用户界面的基本单位。随着应用的复杂度增加,组件之间的通讯变得尤为重要。Vue2提供了多种方式来实现组件之间的通讯,包括父子组件通讯、子父组件通讯、兄弟组件通讯、跨级组件通讯等。本文将详细介绍这些通讯方式,并探讨它们的优缺点及适用场景。

父子组件通讯

Props

Props是Vue中最常用的父子组件通讯方式。通过Props,父组件可以向子组件传递数据。

<!-- 父组件 -->
<template>
  <div>
    <child-component :message="parentMessage"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  props: ['message']
};
</script>

自定义事件

子组件可以通过自定义事件向父组件传递数据。

<!-- 父组件 -->
<template>
  <div>
    <child-component @custom-event="handleEvent"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleEvent(data) {
      console.log('Received data from child:', data);
    }
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <button @click="sendData">Send Data</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('custom-event', 'Hello from child');
    }
  }
};
</script>

v-model

v-model是Vue中的双向绑定指令,常用于表单输入。它实际上是props$emit的语法糖。

<!-- 父组件 -->
<template>
  <div>
    <child-component v-model="parentMessage"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <input :value="value" @input="updateValue">
  </div>
</template>

<script>
export default {
  props: ['value'],
  methods: {
    updateValue(event) {
      this.$emit('input', event.target.value);
    }
  }
};
</script>

.sync修饰符

.sync修饰符是Vue2.3.0+引入的语法糖,用于实现父子组件的双向绑定。

<!-- 父组件 -->
<template>
  <div>
    <child-component :message.sync="parentMessage"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <input :value="message" @input="updateMessage">
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    updateMessage(event) {
      this.$emit('update:message', event.target.value);
    }
  }
};
</script>

子父组件通讯

$emit

子组件通过$emit方法触发父组件的事件,从而实现子父组件通讯。

<!-- 父组件 -->
<template>
  <div>
    <child-component @custom-event="handleEvent"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleEvent(data) {
      console.log('Received data from child:', data);
    }
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <button @click="sendData">Send Data</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('custom-event', 'Hello from child');
    }
  }
};
</script>

v-model

v-model同样可以用于子父组件通讯,通过props$emit实现双向绑定。

<!-- 父组件 -->
<template>
  <div>
    <child-component v-model="parentMessage"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <input :value="value" @input="updateValue">
  </div>
</template>

<script>
export default {
  props: ['value'],
  methods: {
    updateValue(event) {
      this.$emit('input', event.target.value);
    }
  }
};
</script>

.sync修饰符

.sync修饰符同样可以用于子父组件通讯,实现双向绑定。

<!-- 父组件 -->
<template>
  <div>
    <child-component :message.sync="parentMessage"></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from parent'
    };
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <input :value="message" @input="updateMessage">
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    updateMessage(event) {
      this.$emit('update:message', event.target.value);
    }
  }
};
</script>

兄弟组件通讯

事件总线

事件总线是一种简单的兄弟组件通讯方式,通过一个全局的事件总线来实现组件之间的通讯。

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- 组件A -->
<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
import { EventBus } from './eventBus.js';

export default {
  methods: {
    sendMessage() {
      EventBus.$emit('message', 'Hello from Component A');
    }
  }
};
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { EventBus } from './eventBus.js';

export default {
  data() {
    return {
      message: ''
    };
  },
  created() {
    EventBus.$on('message', (data) => {
      this.message = data;
    });
  }
};
</script>

Vuex

Vuex是Vue的官方状态管理库,适用于复杂的应用场景。通过Vuex,兄弟组件可以共享状态。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: ''
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  },
  actions: {
    updateMessage({ commit }, message) {
      commit('setMessage', message);
    }
  }
});
<!-- 组件A -->
<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$store.dispatch('updateMessage', 'Hello from Component A');
    }
  }
};
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message;
    }
  }
};
</script>

跨级组件通讯

provide/inject

provideinject是Vue2.2.0+引入的API,用于实现跨级组件通讯。

<!-- 祖先组件 -->
<template>
  <div>
    <parent-component></parent-component>
  </div>
</template>

<script>
import ParentComponent from './ParentComponent.vue';

export default {
  components: {
    ParentComponent
  },
  provide() {
    return {
      message: 'Hello from ancestor'
    };
  }
};
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  inject: ['message']
};
</script>

Vuex

Vuex同样适用于跨级组件通讯,通过共享状态实现组件之间的通讯。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: ''
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  },
  actions: {
    updateMessage({ commit }, message) {
      commit('setMessage', message);
    }
  }
});
<!-- 祖先组件 -->
<template>
  <div>
    <parent-component></parent-component>
  </div>
</template>

<script>
import ParentComponent from './ParentComponent.vue';

export default {
  components: {
    ParentComponent
  },
  methods: {
    sendMessage() {
      this.$store.dispatch('updateMessage', 'Hello from ancestor');
    }
  }
};
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  }
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message;
    }
  }
};
</script>

全局事件总线

全局事件总线是一种简单的跨组件通讯方式,通过一个全局的Vue实例来实现组件之间的通讯。

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- 组件A -->
<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
import { EventBus } from './eventBus.js';

export default {
  methods: {
    sendMessage() {
      EventBus.$emit('message', 'Hello from Component A');
    }
  }
};
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
import { EventBus } from './eventBus.js';

export default {
  data() {
    return {
      message: ''
    };
  },
  created() {
    EventBus.$on('message', (data) => {
      this.message = data;
    });
  }
};
</script>

Vuex状态管理

Vuex是Vue的官方状态管理库,适用于复杂的应用场景。通过Vuex,组件可以共享状态,实现组件之间的通讯。

State

State是Vuex中的核心概念,用于存储应用的状态。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: ''
  }
});
<!-- 组件A -->
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message;
    }
  }
};
</script>

Getters

Getters用于从state中派生出一些状态,类似于计算属性。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: 'Hello from Vuex'
  },
  getters: {
    uppercaseMessage(state) {
      return state.message.toUpperCase();
    }
  }
});
<!-- 组件A -->
<template>
  <div>
    <p>{{ uppercaseMessage }}</p>
  </div>
</template>

<script>
export default {
  computed: {
    uppercaseMessage() {
      return this.$store.getters.uppercaseMessage;
    }
  }
};
</script>

Mutations

Mutations是唯一可以修改state的方法,必须是同步函数。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: ''
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  }
});
<!-- 组件A -->
<template>
  <div>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
export default {
  methods: {
    updateMessage() {
      this.$store.commit('setMessage', 'Hello from Component A');
    }
  }
};
</script>

Actions

Actions用于处理异步操作,可以包含任意异步操作,最终通过提交mutation来修改state。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: ''
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  },
  actions: {
    updateMessage({ commit }, message) {
      setTimeout(() => {
        commit('setMessage', message);
      }, 1000);
    }
  }
});
<!-- 组件A -->
<template>
  <div>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
export default {
  methods: {
    updateMessage() {
      this.$store.dispatch('updateMessage', 'Hello from Component A');
    }
  }
};
</script>

Modules

Modules用于将store分割成模块,每个模块拥有自己的state、getters、mutations、actions。

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const moduleA = {
  state: {
    message: 'Hello from Module A'
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  },
  actions: {
    updateMessage({ commit }, message) {
      commit('setMessage', message);
    }
  }
};

const moduleB = {
  state: {
    message: 'Hello from Module B'
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    }
  },
  actions: {
    updateMessage({ commit }, message) {
      commit('setMessage', message);
    }
  }
};

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
});
<!-- 组件A -->
<template>
  <div>
    <p>{{ messageA }}</p>
    <button @click="updateMessageA">Update Message A</button>
  </div>
</template>

<script>
export default {
  computed: {
    messageA() {
      return this.$store.state.a.message;
    }
  },
  methods: {
    updateMessageA() {
      this.$store.dispatch('a/updateMessage', 'Updated Message A');
    }
  }
};
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{{ messageB }}</p>
    <button @click="updateMessageB">Update Message B</button>
  </div>
</template>

<script>
export default {
  computed: {
    messageB() {
      return this.$store.state.b.message;
    }
  },
  methods: {
    updateMessageB() {
      this.$store.dispatch('b/updateMessage', 'Updated Message B');
    }
  }
};
</script>

总结

Vue2提供了多种组件通讯方式,包括Props、自定义事件、v-model、.sync修饰符、事件总线、Vuex、provide/inject等。每种方式都有其适用的场景和优缺点。在实际开发中,应根据具体需求选择合适的通讯方式,以确保代码的可维护性和可扩展性。

通过本文的介绍,相信读者已经对Vue2的组件通讯有了更深入的理解。希望这些知识能够帮助你在实际项目中更好地应用Vue2,构建出高效、可维护的前端应用。

推荐阅读:
  1. react组件通讯的方法
  2. Angular父子组件通讯的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:如何使用微信小程序scroll-view实现左右联动效果

下一篇:JavaScript单例模式是什么及怎么实现

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》